Home | History | Annotate | Download | only in drag_drop
      1 // Copyright (c) 2012 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 
      5 #include "ash/drag_drop/drag_drop_controller.h"
      6 
      7 #include "ash/drag_drop/drag_drop_tracker.h"
      8 #include "ash/drag_drop/drag_image_view.h"
      9 #include "ash/shell.h"
     10 #include "ash/test/ash_test_base.h"
     11 #include "base/command_line.h"
     12 #include "base/location.h"
     13 #include "base/strings/utf_string_conversions.h"
     14 #include "ui/aura/client/capture_client.h"
     15 #include "ui/aura/root_window.h"
     16 #include "ui/aura/test/event_generator.h"
     17 #include "ui/base/clipboard/clipboard.h"
     18 #include "ui/base/clipboard/scoped_clipboard_writer.h"
     19 #include "ui/base/dragdrop/drag_drop_types.h"
     20 #include "ui/base/dragdrop/drag_utils.h"
     21 #include "ui/base/dragdrop/os_exchange_data.h"
     22 #include "ui/base/ui_base_switches.h"
     23 #include "ui/events/event.h"
     24 #include "ui/events/event_utils.h"
     25 #include "ui/events/gestures/gesture_types.h"
     26 #include "ui/gfx/animation/linear_animation.h"
     27 #include "ui/gfx/image/image_skia_rep.h"
     28 #include "ui/views/test/test_views_delegate.h"
     29 #include "ui/views/view.h"
     30 #include "ui/views/views_delegate.h"
     31 #include "ui/views/widget/native_widget_aura.h"
     32 #include "ui/views/widget/native_widget_delegate.h"
     33 #include "ui/views/widget/widget.h"
     34 
     35 namespace ash {
     36 namespace test {
     37 
     38 namespace {
     39 
     40 // A simple view that makes sure RunShellDrag is invoked on mouse drag.
     41 class DragTestView : public views::View {
     42  public:
     43   DragTestView() : views::View() {
     44     Reset();
     45   }
     46 
     47   void Reset() {
     48     num_drag_enters_ = 0;
     49     num_drag_exits_ = 0;
     50     num_drag_updates_ = 0;
     51     num_drops_ = 0;
     52     drag_done_received_ = false;
     53     long_tap_received_ = false;
     54   }
     55 
     56   int VerticalDragThreshold() {
     57     return views::View::GetVerticalDragThreshold();
     58   }
     59 
     60   int HorizontalDragThreshold() {
     61     return views::View::GetHorizontalDragThreshold();
     62   }
     63 
     64   int num_drag_enters_;
     65   int num_drag_exits_;
     66   int num_drag_updates_;
     67   int num_drops_;
     68   bool drag_done_received_;
     69   bool long_tap_received_;
     70 
     71  private:
     72   // View overrides:
     73   virtual int GetDragOperations(const gfx::Point& press_pt) OVERRIDE {
     74     return ui::DragDropTypes::DRAG_COPY;
     75   }
     76 
     77   virtual void WriteDragData(const gfx::Point& p,
     78                              OSExchangeData* data) OVERRIDE {
     79     data->SetString(UTF8ToUTF16("I am being dragged"));
     80     gfx::ImageSkiaRep image_rep(gfx::Size(10, 20), 1.0f);
     81     gfx::ImageSkia image_skia(image_rep);
     82 
     83     drag_utils::SetDragImageOnDataObject(
     84         image_skia, image_skia.size(), gfx::Vector2d(), data);
     85   }
     86 
     87   virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
     88     return true;
     89   }
     90 
     91   virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
     92     if (event->type() == ui::ET_GESTURE_LONG_TAP)
     93       long_tap_received_ = true;
     94     return;
     95   }
     96 
     97   virtual bool GetDropFormats(
     98       int* formats,
     99       std::set<OSExchangeData::CustomFormat>* custom_formats) OVERRIDE {
    100     *formats = ui::OSExchangeData::STRING;
    101     return true;
    102   }
    103 
    104   virtual bool CanDrop(const OSExchangeData& data) OVERRIDE {
    105     return true;
    106   }
    107 
    108   virtual void OnDragEntered(const ui::DropTargetEvent& event) OVERRIDE {
    109     num_drag_enters_++;
    110   }
    111 
    112   virtual int OnDragUpdated(const ui::DropTargetEvent& event) OVERRIDE {
    113     num_drag_updates_++;
    114     return ui::DragDropTypes::DRAG_COPY;
    115   }
    116 
    117   virtual void OnDragExited() OVERRIDE {
    118     num_drag_exits_++;
    119   }
    120 
    121   virtual int OnPerformDrop(const ui::DropTargetEvent& event) OVERRIDE {
    122     num_drops_++;
    123     return ui::DragDropTypes::DRAG_COPY;
    124   }
    125 
    126   virtual void OnDragDone() OVERRIDE {
    127     drag_done_received_ = true;
    128   }
    129 
    130   DISALLOW_COPY_AND_ASSIGN(DragTestView);
    131 };
    132 
    133 class CompletableLinearAnimation : public gfx::LinearAnimation {
    134  public:
    135   CompletableLinearAnimation(int duration,
    136                              int frame_rate,
    137                              gfx::AnimationDelegate* delegate)
    138       : gfx::LinearAnimation(duration, frame_rate, delegate),
    139         duration_(duration) {
    140   }
    141 
    142   void Complete() {
    143     Step(start_time() + base::TimeDelta::FromMilliseconds(duration_));
    144   }
    145 
    146  private:
    147   int duration_;
    148 };
    149 
    150 class TestDragDropController : public internal::DragDropController {
    151  public:
    152   TestDragDropController() : internal::DragDropController() {
    153     Reset();
    154   }
    155 
    156   void Reset() {
    157     drag_start_received_ = false;
    158     num_drag_updates_ = 0;
    159     drop_received_ = false;
    160     drag_canceled_ = false;
    161     drag_string_.clear();
    162   }
    163 
    164   virtual int StartDragAndDrop(
    165       const ui::OSExchangeData& data,
    166       aura::Window* root_window,
    167       aura::Window* source_window,
    168       const gfx::Point& location,
    169       int operation,
    170       ui::DragDropTypes::DragEventSource source) OVERRIDE {
    171     drag_start_received_ = true;
    172     data.GetString(&drag_string_);
    173     return DragDropController::StartDragAndDrop(
    174         data, root_window, source_window, location, operation, source);
    175   }
    176 
    177   virtual void DragUpdate(aura::Window* target,
    178                           const ui::LocatedEvent& event) OVERRIDE {
    179     DragDropController::DragUpdate(target, event);
    180     num_drag_updates_++;
    181   }
    182 
    183   virtual void Drop(aura::Window* target,
    184                     const ui::LocatedEvent& event) OVERRIDE {
    185     DragDropController::Drop(target, event);
    186     drop_received_ = true;
    187   }
    188 
    189   virtual void DragCancel() OVERRIDE {
    190     DragDropController::DragCancel();
    191     drag_canceled_ = true;
    192   }
    193 
    194   virtual gfx::LinearAnimation* CreateCancelAnimation(
    195       int duration,
    196       int frame_rate,
    197       gfx::AnimationDelegate* delegate) OVERRIDE {
    198     return new CompletableLinearAnimation(duration, frame_rate, delegate);
    199   }
    200 
    201   virtual void DoDragCancel(int animation_duration_ms) OVERRIDE {
    202     DragDropController::DoDragCancel(animation_duration_ms);
    203     drag_canceled_ = true;
    204   }
    205 
    206   bool drag_start_received_;
    207   int num_drag_updates_;
    208   bool drop_received_;
    209   bool drag_canceled_;
    210   base::string16 drag_string_;
    211 
    212  private:
    213   DISALLOW_COPY_AND_ASSIGN(TestDragDropController);
    214 };
    215 
    216 class TestNativeWidgetAura : public views::NativeWidgetAura {
    217  public:
    218   explicit TestNativeWidgetAura(views::internal::NativeWidgetDelegate* delegate)
    219       : NativeWidgetAura(delegate),
    220         check_if_capture_lost_(false) {
    221   }
    222 
    223   void set_check_if_capture_lost(bool value) {
    224     check_if_capture_lost_ = value;
    225   }
    226 
    227   virtual void OnCaptureLost() OVERRIDE {
    228     DCHECK(!check_if_capture_lost_);
    229     views::NativeWidgetAura::OnCaptureLost();
    230   }
    231 
    232  private:
    233   bool check_if_capture_lost_;
    234 
    235   DISALLOW_COPY_AND_ASSIGN(TestNativeWidgetAura);
    236 };
    237 
    238 // TODO(sky): this is for debugging, remove when track down failure.
    239 void SetCheckIfCaptureLost(views::Widget* widget, bool value) {
    240   // On Windows, the DCHECK triggers when running on bot or locally through RDP,
    241   // but not when logged in locally.
    242 #if !defined(OS_WIN)
    243   static_cast<TestNativeWidgetAura*>(widget->native_widget())->
    244       set_check_if_capture_lost(value);
    245 #endif
    246 }
    247 
    248 views::Widget* CreateNewWidget() {
    249   views::Widget* widget = new views::Widget;
    250   views::Widget::InitParams params;
    251   params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
    252   params.accept_events = true;
    253   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    254   params.parent = Shell::GetPrimaryRootWindow();
    255   params.child = true;
    256   params.native_widget = new TestNativeWidgetAura(widget);
    257   widget->Init(params);
    258   widget->Show();
    259   return widget;
    260 }
    261 
    262 void AddViewToWidgetAndResize(views::Widget* widget, views::View* view) {
    263   if (!widget->GetContentsView()) {
    264     views::View* contents_view = new views::View;
    265     widget->SetContentsView(contents_view);
    266   }
    267 
    268   views::View* contents_view = widget->GetContentsView();
    269   contents_view->AddChildView(view);
    270   view->SetBounds(contents_view->width(), 0, 100, 100);
    271   gfx::Rect contents_view_bounds = contents_view->bounds();
    272   contents_view_bounds.Union(view->bounds());
    273   contents_view->SetBoundsRect(contents_view_bounds);
    274   widget->SetBounds(contents_view_bounds);
    275 }
    276 
    277 void DispatchGesture(ui::EventType gesture_type, gfx::Point location) {
    278   ui::GestureEvent gesture_event(
    279       gesture_type,
    280       location.x(),
    281       location.y(),
    282       0,
    283       ui::EventTimeForNow(),
    284       ui::GestureEventDetails(gesture_type, 0, 0),
    285       1);
    286   Shell::GetPrimaryRootWindow()->GetDispatcher()->DispatchGestureEvent(
    287       &gesture_event);
    288 }
    289 
    290 }  // namespace
    291 
    292 class DragDropControllerTest : public AshTestBase {
    293  public:
    294   DragDropControllerTest() : AshTestBase() {}
    295   virtual ~DragDropControllerTest() {}
    296 
    297   virtual void SetUp() OVERRIDE {
    298     AshTestBase::SetUp();
    299     drag_drop_controller_.reset(new TestDragDropController);
    300     drag_drop_controller_->set_should_block_during_drag_drop(false);
    301     aura::client::SetDragDropClient(Shell::GetPrimaryRootWindow(),
    302                                     drag_drop_controller_.get());
    303     views_delegate_.reset(new views::TestViewsDelegate);
    304   }
    305 
    306   virtual void TearDown() OVERRIDE {
    307     aura::client::SetDragDropClient(Shell::GetPrimaryRootWindow(), NULL);
    308     drag_drop_controller_.reset();
    309     AshTestBase::TearDown();
    310   }
    311 
    312   void UpdateDragData(ui::OSExchangeData* data) {
    313     drag_drop_controller_->drag_data_ = data;
    314   }
    315 
    316   aura::Window* GetDragWindow() {
    317     return drag_drop_controller_->drag_window_;
    318   }
    319 
    320   aura::Window* GetDragSourceWindow() {
    321     return drag_drop_controller_->drag_source_window_;
    322   }
    323 
    324   void SetDragSourceWindow(aura::Window* drag_source_window) {
    325     drag_drop_controller_->drag_source_window_ = drag_source_window;
    326     drag_source_window->AddObserver(drag_drop_controller_.get());
    327   }
    328 
    329   aura::Window* GetDragImageWindow() {
    330     return drag_drop_controller_->drag_image_.get() ?
    331         drag_drop_controller_->drag_image_->GetWidget()->GetNativeWindow() :
    332         NULL;
    333   }
    334 
    335   internal::DragDropTracker* drag_drop_tracker() {
    336     return drag_drop_controller_->drag_drop_tracker_.get();
    337   }
    338 
    339   void CompleteCancelAnimation() {
    340     CompletableLinearAnimation* animation =
    341         static_cast<CompletableLinearAnimation*>(
    342             drag_drop_controller_->cancel_animation_.get());
    343     animation->Complete();
    344   }
    345 
    346  protected:
    347   scoped_ptr<TestDragDropController> drag_drop_controller_;
    348   scoped_ptr<views::TestViewsDelegate> views_delegate_;
    349 
    350  private:
    351   DISALLOW_COPY_AND_ASSIGN(DragDropControllerTest);
    352 };
    353 
    354 // TODO(win_aura) http://crbug.com/154081
    355 #if defined(OS_WIN)
    356 #define MAYBE_DragDropInSingleViewTest DISABLED_DragDropInSingleViewTest
    357 #else
    358 #define MAYBE_DragDropInSingleViewTest DragDropInSingleViewTest
    359 #endif
    360 TEST_F(DragDropControllerTest, MAYBE_DragDropInSingleViewTest) {
    361   scoped_ptr<views::Widget> widget(CreateNewWidget());
    362   DragTestView* drag_view = new DragTestView;
    363   AddViewToWidgetAndResize(widget.get(), drag_view);
    364   ui::OSExchangeData data;
    365   data.SetString(UTF8ToUTF16("I am being dragged"));
    366   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    367                                        widget->GetNativeView());
    368   generator.PressLeftButton();
    369 
    370   int num_drags = 17;
    371   SetCheckIfCaptureLost(widget.get(), true);
    372   for (int i = 0; i < num_drags; ++i) {
    373     // Because we are not doing a blocking drag and drop, the original
    374     // OSDragExchangeData object is lost as soon as we return from the drag
    375     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    376     // drag_data_ to a fake drag data object that we created.
    377     if (i > 0)
    378       UpdateDragData(&data);
    379     // 7 comes from views::View::GetVerticalDragThreshold()).
    380     if (i >= 7)
    381       SetCheckIfCaptureLost(widget.get(), false);
    382 
    383     generator.MoveMouseBy(0, 1);
    384 
    385     // Execute any scheduled draws to process deferred mouse events.
    386     RunAllPendingInMessageLoop();
    387   }
    388 
    389   generator.ReleaseLeftButton();
    390 
    391   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    392   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    393       drag_drop_controller_->num_drag_updates_);
    394   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    395   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    396       drag_drop_controller_->drag_string_);
    397 
    398   EXPECT_EQ(1, drag_view->num_drag_enters_);
    399   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    400       drag_view->num_drag_updates_);
    401   EXPECT_EQ(1, drag_view->num_drops_);
    402   EXPECT_EQ(0, drag_view->num_drag_exits_);
    403   EXPECT_TRUE(drag_view->drag_done_received_);
    404 }
    405 
    406 TEST_F(DragDropControllerTest, DragDropWithZeroDragUpdates) {
    407   scoped_ptr<views::Widget> widget(CreateNewWidget());
    408   DragTestView* drag_view = new DragTestView;
    409   AddViewToWidgetAndResize(widget.get(), drag_view);
    410   ui::OSExchangeData data;
    411   data.SetString(UTF8ToUTF16("I am being dragged"));
    412   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    413                                        widget->GetNativeView());
    414   generator.PressLeftButton();
    415 
    416   int num_drags = drag_view->VerticalDragThreshold() + 1;
    417   for (int i = 0; i < num_drags; ++i) {
    418     // Because we are not doing a blocking drag and drop, the original
    419     // OSDragExchangeData object is lost as soon as we return from the drag
    420     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    421     // drag_data_ to a fake drag data object that we created.
    422     if (i > 0)
    423       UpdateDragData(&data);
    424     generator.MoveMouseBy(0, 1);
    425   }
    426 
    427   UpdateDragData(&data);
    428 
    429   generator.ReleaseLeftButton();
    430 
    431   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    432   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold() + 1,
    433       drag_drop_controller_->num_drag_updates_);
    434   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    435 
    436   EXPECT_EQ(1, drag_view->num_drag_enters_);
    437   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold() + 1,
    438       drag_view->num_drag_updates_);
    439   EXPECT_EQ(1, drag_view->num_drops_);
    440   EXPECT_EQ(0, drag_view->num_drag_exits_);
    441   EXPECT_TRUE(drag_view->drag_done_received_);
    442 }
    443 
    444 // TODO(win_aura) http://crbug.com/154081
    445 #if defined(OS_WIN)
    446 #define MAYBE_DragDropInMultipleViewsSingleWidgetTest DISABLED_DragDropInMultipleViewsSingleWidgetTest
    447 #else
    448 #define MAYBE_DragDropInMultipleViewsSingleWidgetTest DragDropInMultipleViewsSingleWidgetTest
    449 #endif
    450 TEST_F(DragDropControllerTest, MAYBE_DragDropInMultipleViewsSingleWidgetTest) {
    451   scoped_ptr<views::Widget> widget(CreateNewWidget());
    452   DragTestView* drag_view1 = new DragTestView;
    453   AddViewToWidgetAndResize(widget.get(), drag_view1);
    454   DragTestView* drag_view2 = new DragTestView;
    455   AddViewToWidgetAndResize(widget.get(), drag_view2);
    456 
    457   ui::OSExchangeData data;
    458   data.SetString(UTF8ToUTF16("I am being dragged"));
    459 
    460   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
    461   generator.MoveMouseRelativeTo(widget->GetNativeView(),
    462                                 drag_view1->bounds().CenterPoint());
    463   generator.PressLeftButton();
    464 
    465   int num_drags = drag_view1->width();
    466   for (int i = 0; i < num_drags; ++i) {
    467     // Because we are not doing a blocking drag and drop, the original
    468     // OSDragExchangeData object is lost as soon as we return from the drag
    469     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    470     // drag_data_ to a fake drag data object that we created.
    471     if (i > 0)
    472       UpdateDragData(&data);
    473     generator.MoveMouseBy(1, 0);
    474 
    475     // Execute any scheduled draws to process deferred mouse events.
    476     RunAllPendingInMessageLoop();
    477   }
    478 
    479   generator.ReleaseLeftButton();
    480 
    481   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    482   EXPECT_EQ(num_drags - 1 - drag_view1->HorizontalDragThreshold(),
    483       drag_drop_controller_->num_drag_updates_);
    484   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    485   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    486       drag_drop_controller_->drag_string_);
    487 
    488   EXPECT_EQ(1, drag_view1->num_drag_enters_);
    489   int num_expected_updates = drag_view1->bounds().width() -
    490       drag_view1->bounds().CenterPoint().x() - 2;
    491   EXPECT_EQ(num_expected_updates - drag_view1->HorizontalDragThreshold(),
    492       drag_view1->num_drag_updates_);
    493   EXPECT_EQ(0, drag_view1->num_drops_);
    494   EXPECT_EQ(1, drag_view1->num_drag_exits_);
    495   EXPECT_TRUE(drag_view1->drag_done_received_);
    496 
    497   EXPECT_EQ(1, drag_view2->num_drag_enters_);
    498   num_expected_updates = num_drags - num_expected_updates - 1;
    499   EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_);
    500   EXPECT_EQ(1, drag_view2->num_drops_);
    501   EXPECT_EQ(0, drag_view2->num_drag_exits_);
    502   EXPECT_FALSE(drag_view2->drag_done_received_);
    503 }
    504 
    505 // TODO(win_aura) http://crbug.com/154081
    506 #if defined(OS_WIN)
    507 #define MAYBE_DragDropInMultipleViewsMultipleWidgetsTest DISABLED_DragDropInMultipleViewsMultipleWidgetsTest
    508 #else
    509 #define MAYBE_DragDropInMultipleViewsMultipleWidgetsTest DragDropInMultipleViewsMultipleWidgetsTest
    510 #endif
    511 TEST_F(DragDropControllerTest, MAYBE_DragDropInMultipleViewsMultipleWidgetsTest) {
    512   scoped_ptr<views::Widget> widget1(CreateNewWidget());
    513   DragTestView* drag_view1 = new DragTestView;
    514   AddViewToWidgetAndResize(widget1.get(), drag_view1);
    515   scoped_ptr<views::Widget> widget2(CreateNewWidget());
    516   DragTestView* drag_view2 = new DragTestView;
    517   AddViewToWidgetAndResize(widget2.get(), drag_view2);
    518   gfx::Rect widget1_bounds = widget1->GetClientAreaBoundsInScreen();
    519   gfx::Rect widget2_bounds = widget2->GetClientAreaBoundsInScreen();
    520   widget2->SetBounds(gfx::Rect(widget1_bounds.width(), 0,
    521       widget2_bounds.width(), widget2_bounds.height()));
    522 
    523   ui::OSExchangeData data;
    524   data.SetString(UTF8ToUTF16("I am being dragged"));
    525 
    526   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    527                                        widget1->GetNativeView());
    528   generator.PressLeftButton();
    529 
    530   int num_drags = drag_view1->width();
    531   for (int i = 0; i < num_drags; ++i) {
    532     // Because we are not doing a blocking drag and drop, the original
    533     // OSDragExchangeData object is lost as soon as we return from the drag
    534     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    535     // drag_data_ to a fake drag data object that we created.
    536     if (i > 0)
    537       UpdateDragData(&data);
    538     generator.MoveMouseBy(1, 0);
    539 
    540     // Execute any scheduled draws to process deferred mouse events.
    541     RunAllPendingInMessageLoop();
    542   }
    543 
    544   generator.ReleaseLeftButton();
    545 
    546   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    547   EXPECT_EQ(num_drags - 1 - drag_view1->HorizontalDragThreshold(),
    548       drag_drop_controller_->num_drag_updates_);
    549   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    550   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    551       drag_drop_controller_->drag_string_);
    552 
    553   EXPECT_EQ(1, drag_view1->num_drag_enters_);
    554   int num_expected_updates = drag_view1->bounds().width() -
    555       drag_view1->bounds().CenterPoint().x() - 2;
    556   EXPECT_EQ(num_expected_updates - drag_view1->HorizontalDragThreshold(),
    557       drag_view1->num_drag_updates_);
    558   EXPECT_EQ(0, drag_view1->num_drops_);
    559   EXPECT_EQ(1, drag_view1->num_drag_exits_);
    560   EXPECT_TRUE(drag_view1->drag_done_received_);
    561 
    562   EXPECT_EQ(1, drag_view2->num_drag_enters_);
    563   num_expected_updates = num_drags - num_expected_updates - 1;
    564   EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_);
    565   EXPECT_EQ(1, drag_view2->num_drops_);
    566   EXPECT_EQ(0, drag_view2->num_drag_exits_);
    567   EXPECT_FALSE(drag_view2->drag_done_received_);
    568 }
    569 
    570 // TODO(win_aura) http://crbug.com/154081
    571 #if defined(OS_WIN)
    572 #define MAYBE_ViewRemovedWhileInDragDropTest DISABLED_ViewRemovedWhileInDragDropTest
    573 #else
    574 #define MAYBE_ViewRemovedWhileInDragDropTest ViewRemovedWhileInDragDropTest
    575 #endif
    576 TEST_F(DragDropControllerTest, MAYBE_ViewRemovedWhileInDragDropTest) {
    577   scoped_ptr<views::Widget> widget(CreateNewWidget());
    578   scoped_ptr<DragTestView> drag_view(new DragTestView);
    579   AddViewToWidgetAndResize(widget.get(), drag_view.get());
    580   gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
    581   ui::OSExchangeData data;
    582   data.SetString(UTF8ToUTF16("I am being dragged"));
    583 
    584   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
    585   generator.MoveMouseToCenterOf(widget->GetNativeView());
    586   generator.PressLeftButton();
    587 
    588   int num_drags_1 = 17;
    589   for (int i = 0; i < num_drags_1; ++i) {
    590     // Because we are not doing a blocking drag and drop, the original
    591     // OSDragExchangeData object is lost as soon as we return from the drag
    592     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    593     // drag_data_ to a fake drag data object that we created.
    594     if (i > 0)
    595       UpdateDragData(&data);
    596     generator.MoveMouseBy(0, 1);
    597 
    598     // Execute any scheduled draws to process deferred mouse events.
    599     RunAllPendingInMessageLoop();
    600   }
    601 
    602   drag_view->parent()->RemoveChildView(drag_view.get());
    603   // View has been removed. We will not get any of the following drag updates.
    604   int num_drags_2 = 23;
    605   for (int i = 0; i < num_drags_2; ++i) {
    606     UpdateDragData(&data);
    607     generator.MoveMouseBy(0, 1);
    608 
    609     // Execute any scheduled draws to process deferred mouse events.
    610     RunAllPendingInMessageLoop();
    611   }
    612 
    613   generator.ReleaseLeftButton();
    614 
    615   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    616   EXPECT_EQ(num_drags_1 + num_drags_2 - 1 - drag_view->VerticalDragThreshold(),
    617       drag_drop_controller_->num_drag_updates_);
    618   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    619   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    620       drag_drop_controller_->drag_string_);
    621 
    622   EXPECT_EQ(1, drag_view->num_drag_enters_);
    623   EXPECT_EQ(num_drags_1 - 1 - drag_view->VerticalDragThreshold(),
    624       drag_view->num_drag_updates_);
    625   EXPECT_EQ(0, drag_view->num_drops_);
    626   EXPECT_EQ(0, drag_view->num_drag_exits_);
    627   EXPECT_TRUE(drag_view->drag_done_received_);
    628 }
    629 
    630 TEST_F(DragDropControllerTest, DragLeavesClipboardAloneTest) {
    631   ui::Clipboard* cb = ui::Clipboard::GetForCurrentThread();
    632   std::string clip_str("I am on the clipboard");
    633   {
    634     // We first copy some text to the clipboard.
    635     ui::ScopedClipboardWriter scw(cb, ui::CLIPBOARD_TYPE_COPY_PASTE);
    636     scw.WriteText(ASCIIToUTF16(clip_str));
    637   }
    638   EXPECT_TRUE(cb->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
    639       ui::CLIPBOARD_TYPE_COPY_PASTE));
    640 
    641   scoped_ptr<views::Widget> widget(CreateNewWidget());
    642   DragTestView* drag_view = new DragTestView;
    643   AddViewToWidgetAndResize(widget.get(), drag_view);
    644 
    645   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    646                                        widget->GetNativeView());
    647   ui::OSExchangeData data;
    648   std::string data_str("I am being dragged");
    649   data.SetString(ASCIIToUTF16(data_str));
    650 
    651   generator.PressLeftButton();
    652   generator.MoveMouseBy(0, drag_view->VerticalDragThreshold() + 1);
    653 
    654   // Execute any scheduled draws to process deferred mouse events.
    655   RunAllPendingInMessageLoop();
    656 
    657   // Verify the clipboard contents haven't changed
    658   std::string result;
    659   EXPECT_TRUE(cb->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
    660       ui::CLIPBOARD_TYPE_COPY_PASTE));
    661   cb->ReadAsciiText(ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
    662   EXPECT_EQ(clip_str, result);
    663   // Destory the clipboard here because ash doesn't delete it.
    664   // crbug.com/158150.
    665   ui::Clipboard::DestroyClipboardForCurrentThread();
    666 }
    667 
    668 TEST_F(DragDropControllerTest, WindowDestroyedDuringDragDrop) {
    669   scoped_ptr<views::Widget> widget(CreateNewWidget());
    670   DragTestView* drag_view = new DragTestView;
    671   AddViewToWidgetAndResize(widget.get(), drag_view);
    672   aura::Window* window = widget->GetNativeView();
    673 
    674   ui::OSExchangeData data;
    675   data.SetString(UTF8ToUTF16("I am being dragged"));
    676   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    677                                        widget->GetNativeView());
    678   generator.PressLeftButton();
    679 
    680   int num_drags = 17;
    681   for (int i = 0; i < num_drags; ++i) {
    682     // Because we are not doing a blocking drag and drop, the original
    683     // OSDragExchangeData object is lost as soon as we return from the drag
    684     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    685     // drag_data_ to a fake drag data object that we created.
    686     if (i > 0)
    687       UpdateDragData(&data);
    688     generator.MoveMouseBy(0, 1);
    689 
    690     // Execute any scheduled draws to process deferred mouse events.
    691     RunAllPendingInMessageLoop();
    692 
    693     if (i > drag_view->VerticalDragThreshold())
    694       EXPECT_EQ(window, GetDragWindow());
    695   }
    696 
    697   widget->CloseNow();
    698   EXPECT_FALSE(GetDragWindow());
    699 
    700   num_drags = 23;
    701   for (int i = 0; i < num_drags; ++i) {
    702     if (i > 0)
    703       UpdateDragData(&data);
    704     generator.MoveMouseBy(0, 1);
    705     // We should not crash here.
    706   }
    707 
    708   generator.ReleaseLeftButton();
    709 
    710   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    711   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    712 }
    713 
    714 TEST_F(DragDropControllerTest, SyntheticEventsDuringDragDrop) {
    715   scoped_ptr<views::Widget> widget(CreateNewWidget());
    716   DragTestView* drag_view = new DragTestView;
    717   AddViewToWidgetAndResize(widget.get(), drag_view);
    718   ui::OSExchangeData data;
    719   data.SetString(UTF8ToUTF16("I am being dragged"));
    720   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    721                                        widget->GetNativeView());
    722   generator.PressLeftButton();
    723 
    724   int num_drags = 17;
    725   for (int i = 0; i < num_drags; ++i) {
    726     // Because we are not doing a blocking drag and drop, the original
    727     // OSDragExchangeData object is lost as soon as we return from the drag
    728     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    729     // drag_data_ to a fake drag data object that we created.
    730     if (i > 0)
    731       UpdateDragData(&data);
    732     generator.MoveMouseBy(0, 1);
    733 
    734     // We send a unexpected mouse move event. Note that we cannot use
    735     // EventGenerator since it implicitly turns these into mouse drag events.
    736     // The DragDropController should simply ignore these events.
    737     gfx::Point mouse_move_location = drag_view->bounds().CenterPoint();
    738     ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, mouse_move_location,
    739                               mouse_move_location, 0);
    740     Shell::GetPrimaryRootWindow()->GetDispatcher()->AsRootWindowHostDelegate()->
    741         OnHostMouseEvent(&mouse_move);
    742   }
    743 
    744   generator.ReleaseLeftButton();
    745 
    746   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    747   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    748       drag_drop_controller_->num_drag_updates_);
    749   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    750   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    751       drag_drop_controller_->drag_string_);
    752 
    753   EXPECT_EQ(1, drag_view->num_drag_enters_);
    754   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    755       drag_view->num_drag_updates_);
    756   EXPECT_EQ(1, drag_view->num_drops_);
    757   EXPECT_EQ(0, drag_view->num_drag_exits_);
    758   EXPECT_TRUE(drag_view->drag_done_received_);
    759 }
    760 
    761 // TODO(win_aura) http://crbug.com/154081
    762 #if defined(OS_WIN)
    763 #define MAYBE_PressingEscapeCancelsDragDrop DISABLED_PressingEscapeCancelsDragDrop
    764 #define MAYBE_CaptureLostCancelsDragDrop DISABLED_CaptureLostCancelsDragDrop
    765 #else
    766 #define MAYBE_PressingEscapeCancelsDragDrop PressingEscapeCancelsDragDrop
    767 #define MAYBE_CaptureLostCancelsDragDrop CaptureLostCancelsDragDrop
    768 #endif
    769 TEST_F(DragDropControllerTest, MAYBE_PressingEscapeCancelsDragDrop) {
    770   scoped_ptr<views::Widget> widget(CreateNewWidget());
    771   DragTestView* drag_view = new DragTestView;
    772   AddViewToWidgetAndResize(widget.get(), drag_view);
    773   ui::OSExchangeData data;
    774   data.SetString(UTF8ToUTF16("I am being dragged"));
    775   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    776                                        widget->GetNativeView());
    777   generator.PressLeftButton();
    778 
    779   int num_drags = 17;
    780   for (int i = 0; i < num_drags; ++i) {
    781     // Because we are not doing a blocking drag and drop, the original
    782     // OSDragExchangeData object is lost as soon as we return from the drag
    783     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    784     // drag_data_ to a fake drag data object that we created.
    785     if (i > 0)
    786       UpdateDragData(&data);
    787     generator.MoveMouseBy(0, 1);
    788 
    789     // Execute any scheduled draws to process deferred mouse events.
    790     RunAllPendingInMessageLoop();
    791   }
    792 
    793   generator.PressKey(ui::VKEY_ESCAPE, 0);
    794 
    795   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    796   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    797       drag_drop_controller_->num_drag_updates_);
    798   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    799   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    800   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    801       drag_drop_controller_->drag_string_);
    802 
    803   EXPECT_EQ(1, drag_view->num_drag_enters_);
    804   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    805       drag_view->num_drag_updates_);
    806   EXPECT_EQ(0, drag_view->num_drops_);
    807   EXPECT_EQ(1, drag_view->num_drag_exits_);
    808   EXPECT_TRUE(drag_view->drag_done_received_);
    809 }
    810 
    811 TEST_F(DragDropControllerTest, MAYBE_CaptureLostCancelsDragDrop) {
    812   scoped_ptr<views::Widget> widget(CreateNewWidget());
    813   DragTestView* drag_view = new DragTestView;
    814   AddViewToWidgetAndResize(widget.get(), drag_view);
    815   ui::OSExchangeData data;
    816   data.SetString(UTF8ToUTF16("I am being dragged"));
    817   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    818                                        widget->GetNativeView());
    819   generator.PressLeftButton();
    820 
    821   int num_drags = 17;
    822   for (int i = 0; i < num_drags; ++i) {
    823     // Because we are not doing a blocking drag and drop, the original
    824     // OSDragExchangeData object is lost as soon as we return from the drag
    825     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    826     // drag_data_ to a fake drag data object that we created.
    827     if (i > 0)
    828       UpdateDragData(&data);
    829     generator.MoveMouseBy(0, 1);
    830 
    831     // Execute any scheduled draws to process deferred mouse events.
    832     RunAllPendingInMessageLoop();
    833   }
    834   // Make sure the capture window won't handle mouse events.
    835   aura::Window* capture_window = drag_drop_tracker()->capture_window();
    836   ASSERT_TRUE(!!capture_window);
    837   EXPECT_EQ("0x0", capture_window->bounds().size().ToString());
    838   EXPECT_EQ(NULL,
    839             capture_window->GetEventHandlerForPoint(gfx::Point()));
    840   EXPECT_EQ(NULL,
    841             capture_window->GetTopWindowContainingPoint(gfx::Point()));
    842 
    843   aura::client::GetCaptureClient(widget->GetNativeView()->GetRootWindow())->
    844       SetCapture(NULL);
    845 
    846   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    847   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    848       drag_drop_controller_->num_drag_updates_);
    849   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    850   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    851   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    852       drag_drop_controller_->drag_string_);
    853 
    854   EXPECT_EQ(1, drag_view->num_drag_enters_);
    855   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    856       drag_view->num_drag_updates_);
    857   EXPECT_EQ(0, drag_view->num_drops_);
    858   EXPECT_EQ(1, drag_view->num_drag_exits_);
    859   EXPECT_TRUE(drag_view->drag_done_received_);
    860 }
    861 
    862 TEST_F(DragDropControllerTest, TouchDragDropInMultipleWindows) {
    863   CommandLine::ForCurrentProcess()->AppendSwitch(
    864       switches::kEnableTouchDragDrop);
    865   scoped_ptr<views::Widget> widget1(CreateNewWidget());
    866   DragTestView* drag_view1 = new DragTestView;
    867   AddViewToWidgetAndResize(widget1.get(), drag_view1);
    868   scoped_ptr<views::Widget> widget2(CreateNewWidget());
    869   DragTestView* drag_view2 = new DragTestView;
    870   AddViewToWidgetAndResize(widget2.get(), drag_view2);
    871   gfx::Rect widget1_bounds = widget1->GetClientAreaBoundsInScreen();
    872   gfx::Rect widget2_bounds = widget2->GetClientAreaBoundsInScreen();
    873   widget2->SetBounds(gfx::Rect(widget1_bounds.width(), 0,
    874       widget2_bounds.width(), widget2_bounds.height()));
    875 
    876   ui::OSExchangeData data;
    877   data.SetString(UTF8ToUTF16("I am being dragged"));
    878 
    879   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    880                                        widget1->GetNativeView());
    881   generator.PressTouch();
    882   gfx::Point point = gfx::Rect(drag_view1->bounds()).CenterPoint();
    883   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    884   // Because we are not doing a blocking drag and drop, the original
    885   // OSDragExchangeData object is lost as soon as we return from the drag
    886   // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    887   // drag_data_ to a fake drag data object that we created.
    888   UpdateDragData(&data);
    889   gfx::Point gesture_location = point;
    890   int num_drags = drag_view1->width();
    891   for (int i = 0; i < num_drags; ++i) {
    892     gesture_location.Offset(1, 0);
    893     DispatchGesture(ui::ET_GESTURE_SCROLL_UPDATE, gesture_location);
    894 
    895     // Execute any scheduled draws to process deferred mouse events.
    896     RunAllPendingInMessageLoop();
    897   }
    898 
    899   DispatchGesture(ui::ET_GESTURE_SCROLL_END, gesture_location);
    900 
    901   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    902   EXPECT_EQ(num_drags, drag_drop_controller_->num_drag_updates_);
    903   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    904   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    905       drag_drop_controller_->drag_string_);
    906 
    907   EXPECT_EQ(1, drag_view1->num_drag_enters_);
    908   int num_expected_updates = drag_view1->bounds().width() -
    909       drag_view1->bounds().CenterPoint().x() - 1;
    910   EXPECT_EQ(num_expected_updates, drag_view1->num_drag_updates_);
    911   EXPECT_EQ(0, drag_view1->num_drops_);
    912   EXPECT_EQ(1, drag_view1->num_drag_exits_);
    913   EXPECT_TRUE(drag_view1->drag_done_received_);
    914 
    915   EXPECT_EQ(1, drag_view2->num_drag_enters_);
    916   num_expected_updates = num_drags - num_expected_updates;
    917   EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_);
    918   EXPECT_EQ(1, drag_view2->num_drops_);
    919   EXPECT_EQ(0, drag_view2->num_drag_exits_);
    920   EXPECT_FALSE(drag_view2->drag_done_received_);
    921 }
    922 
    923 TEST_F(DragDropControllerTest, TouchDragDropCancelsOnLongTap) {
    924   CommandLine::ForCurrentProcess()->AppendSwitch(
    925       switches::kEnableTouchDragDrop);
    926   scoped_ptr<views::Widget> widget(CreateNewWidget());
    927   DragTestView* drag_view = new DragTestView;
    928   AddViewToWidgetAndResize(widget.get(), drag_view);
    929   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    930                                        widget->GetNativeView());
    931 
    932   generator.PressTouch();
    933   gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
    934   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    935   DispatchGesture(ui::ET_GESTURE_LONG_TAP, point);
    936 
    937   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    938   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    939   EXPECT_EQ(0, drag_drop_controller_->num_drag_updates_);
    940   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    941   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    942             drag_drop_controller_->drag_string_);
    943   EXPECT_EQ(0, drag_view->num_drag_enters_);
    944   EXPECT_EQ(0, drag_view->num_drops_);
    945   EXPECT_EQ(0, drag_view->num_drag_exits_);
    946   EXPECT_TRUE(drag_view->drag_done_received_);
    947 }
    948 
    949 TEST_F(DragDropControllerTest, TouchDragDropLongTapGestureIsForwarded) {
    950   CommandLine::ForCurrentProcess()->AppendSwitch(
    951       switches::kEnableTouchDragDrop);
    952   scoped_ptr<views::Widget> widget(CreateNewWidget());
    953   DragTestView* drag_view = new DragTestView;
    954   AddViewToWidgetAndResize(widget.get(), drag_view);
    955   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    956                                        widget->GetNativeView());
    957 
    958   generator.PressTouch();
    959   gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
    960   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    961 
    962   // Since we are not running inside a nested loop, the |drag_source_window_|
    963   // will get destroyed immediately. Hence we reassign it.
    964   EXPECT_EQ(NULL, GetDragSourceWindow());
    965   SetDragSourceWindow(widget->GetNativeView());
    966   EXPECT_FALSE(drag_view->long_tap_received_);
    967   DispatchGesture(ui::ET_GESTURE_LONG_TAP, point);
    968   CompleteCancelAnimation();
    969   EXPECT_TRUE(drag_view->long_tap_received_);
    970 }
    971 
    972 namespace {
    973 
    974 class DragImageWindowObserver : public aura::WindowObserver {
    975  public:
    976   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
    977     window_location_on_destroying_ = window->GetBoundsInScreen().origin();
    978   }
    979 
    980   gfx::Point window_location_on_destroying() const {
    981     return window_location_on_destroying_;
    982   }
    983 
    984  public:
    985   gfx::Point window_location_on_destroying_;
    986 };
    987 
    988 }
    989 
    990 // Verifies the drag image moves back to the position where drag is started
    991 // across displays when drag is cancelled.
    992 TEST_F(DragDropControllerTest, DragCancelAcrossDisplays) {
    993   if (!SupportsMultipleDisplays())
    994     return;
    995 
    996   UpdateDisplay("400x400,400x400");
    997   aura::Window::Windows root_windows =
    998       Shell::GetInstance()->GetAllRootWindows();
    999   for (aura::Window::Windows::iterator iter = root_windows.begin();
   1000        iter != root_windows.end(); ++iter) {
   1001     aura::client::SetDragDropClient(*iter, drag_drop_controller_.get());
   1002   }
   1003 
   1004   ui::OSExchangeData data;
   1005   data.SetString(UTF8ToUTF16("I am being dragged"));
   1006   {
   1007     scoped_ptr<views::Widget> widget(CreateNewWidget());
   1008     aura::Window* window = widget->GetNativeWindow();
   1009     drag_drop_controller_->StartDragAndDrop(
   1010         data,
   1011         window->GetRootWindow(),
   1012         window,
   1013         gfx::Point(5, 5),
   1014         ui::DragDropTypes::DRAG_MOVE,
   1015         ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
   1016 
   1017     DragImageWindowObserver observer;
   1018     ASSERT_TRUE(GetDragImageWindow());
   1019     GetDragImageWindow()->AddObserver(&observer);
   1020 
   1021     {
   1022       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1023                        gfx::Point(200, 0),
   1024                        gfx::Point(200, 0),
   1025                        ui::EF_NONE);
   1026       drag_drop_controller_->DragUpdate(window, e);
   1027     }
   1028     {
   1029       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1030                        gfx::Point(600, 0),
   1031                        gfx::Point(600, 0),
   1032                        ui::EF_NONE);
   1033       drag_drop_controller_->DragUpdate(window, e);
   1034     }
   1035 
   1036     drag_drop_controller_->DragCancel();
   1037     CompleteCancelAnimation();
   1038 
   1039     EXPECT_EQ("5,5", observer.window_location_on_destroying().ToString());
   1040   }
   1041 
   1042   {
   1043     scoped_ptr<views::Widget> widget(CreateNewWidget());
   1044     aura::Window* window = widget->GetNativeWindow();
   1045     drag_drop_controller_->StartDragAndDrop(
   1046         data,
   1047         window->GetRootWindow(),
   1048         window,
   1049         gfx::Point(405, 405),
   1050         ui::DragDropTypes::DRAG_MOVE,
   1051         ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
   1052     DragImageWindowObserver observer;
   1053     ASSERT_TRUE(GetDragImageWindow());
   1054     GetDragImageWindow()->AddObserver(&observer);
   1055 
   1056     {
   1057       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1058                        gfx::Point(600, 0),
   1059                        gfx::Point(600, 0),
   1060                        ui::EF_NONE);
   1061       drag_drop_controller_->DragUpdate(window, e);
   1062     }
   1063     {
   1064       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1065                        gfx::Point(200, 0),
   1066                        gfx::Point(200, 0),
   1067                        ui::EF_NONE);
   1068       drag_drop_controller_->DragUpdate(window, e);
   1069     }
   1070 
   1071     drag_drop_controller_->DragCancel();
   1072     CompleteCancelAnimation();
   1073 
   1074     EXPECT_EQ("405,405", observer.window_location_on_destroying().ToString());
   1075   }
   1076   for (aura::Window::Windows::iterator iter = root_windows.begin();
   1077        iter != root_windows.end(); ++iter) {
   1078     aura::client::SetDragDropClient(*iter, NULL);
   1079   }
   1080 }
   1081 
   1082 }  // namespace test
   1083 }  // namespace aura
   1084