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/animation/linear_animation.h"
     18 #include "ui/base/clipboard/clipboard.h"
     19 #include "ui/base/clipboard/scoped_clipboard_writer.h"
     20 #include "ui/base/dragdrop/drag_drop_types.h"
     21 #include "ui/base/dragdrop/drag_utils.h"
     22 #include "ui/base/dragdrop/os_exchange_data.h"
     23 #include "ui/base/events/event.h"
     24 #include "ui/base/events/event_utils.h"
     25 #include "ui/base/gestures/gesture_types.h"
     26 #include "ui/base/ui_base_switches.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), ui::SCALE_FACTOR_100P);
     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 ui::LinearAnimation {
    134  public:
    135   CompletableLinearAnimation(int duration,
    136                              int frame_rate,
    137                              ui::AnimationDelegate* delegate)
    138       : ui::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::RootWindow* 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 ui::LinearAnimation* CreateCancelAnimation(
    195       int duration,
    196       int frame_rate,
    197       ui::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()->DispatchGestureEvent(&gesture_event);
    287 }
    288 
    289 bool IsGestureEventType(ui::EventType type) {
    290   switch (type) {
    291     case ui::ET_GESTURE_SCROLL_BEGIN:
    292     case ui::ET_GESTURE_SCROLL_END:
    293     case ui::ET_GESTURE_SCROLL_UPDATE:
    294     case ui::ET_GESTURE_TAP:
    295     case ui::ET_GESTURE_TAP_CANCEL:
    296     case ui::ET_GESTURE_TAP_DOWN:
    297     case ui::ET_GESTURE_BEGIN:
    298     case ui::ET_GESTURE_END:
    299     case ui::ET_GESTURE_TWO_FINGER_TAP:
    300     case ui::ET_GESTURE_PINCH_BEGIN:
    301     case ui::ET_GESTURE_PINCH_END:
    302     case ui::ET_GESTURE_PINCH_UPDATE:
    303     case ui::ET_GESTURE_LONG_PRESS:
    304     case ui::ET_GESTURE_LONG_TAP:
    305     case ui::ET_GESTURE_MULTIFINGER_SWIPE:
    306     case ui::ET_SCROLL_FLING_CANCEL:
    307     case ui::ET_SCROLL_FLING_START:
    308       return true;
    309     default:
    310       break;
    311   }
    312   return false;
    313 }
    314 
    315 }  // namespace
    316 
    317 class DragDropControllerTest : public AshTestBase {
    318  public:
    319   DragDropControllerTest() : AshTestBase() {}
    320   virtual ~DragDropControllerTest() {}
    321 
    322   virtual void SetUp() OVERRIDE {
    323     AshTestBase::SetUp();
    324     drag_drop_controller_.reset(new TestDragDropController);
    325     drag_drop_controller_->set_should_block_during_drag_drop(false);
    326     aura::client::SetDragDropClient(Shell::GetPrimaryRootWindow(),
    327                                     drag_drop_controller_.get());
    328     views_delegate_.reset(new views::TestViewsDelegate);
    329   }
    330 
    331   virtual void TearDown() OVERRIDE {
    332     aura::client::SetDragDropClient(Shell::GetPrimaryRootWindow(), NULL);
    333     drag_drop_controller_.reset();
    334     AshTestBase::TearDown();
    335   }
    336 
    337   void UpdateDragData(ui::OSExchangeData* data) {
    338     drag_drop_controller_->drag_data_ = data;
    339   }
    340 
    341   aura::Window* GetDragWindow() {
    342     return drag_drop_controller_->drag_window_;
    343   }
    344 
    345   aura::Window* GetDragSourceWindow() {
    346     return drag_drop_controller_->drag_source_window_;
    347   }
    348 
    349   void SetDragSourceWindow(aura::Window* drag_source_window) {
    350     drag_drop_controller_->drag_source_window_ = drag_source_window;
    351     drag_source_window->AddObserver(drag_drop_controller_.get());
    352   }
    353 
    354   aura::Window* GetDragImageWindow() {
    355     return drag_drop_controller_->drag_image_.get() ?
    356         drag_drop_controller_->drag_image_->GetWidget()->GetNativeWindow() :
    357         NULL;
    358   }
    359 
    360   internal::DragDropTracker* drag_drop_tracker() {
    361     return drag_drop_controller_->drag_drop_tracker_.get();
    362   }
    363 
    364   void CompleteCancelAnimation() {
    365     CompletableLinearAnimation* animation =
    366         static_cast<CompletableLinearAnimation*>(
    367             drag_drop_controller_->cancel_animation_.get());
    368     animation->Complete();
    369   }
    370 
    371  protected:
    372   scoped_ptr<TestDragDropController> drag_drop_controller_;
    373   scoped_ptr<views::TestViewsDelegate> views_delegate_;
    374 
    375  private:
    376   DISALLOW_COPY_AND_ASSIGN(DragDropControllerTest);
    377 };
    378 
    379 // TODO(win_aura) http://crbug.com/154081
    380 #if defined(OS_WIN)
    381 #define MAYBE_DragDropInSingleViewTest DISABLED_DragDropInSingleViewTest
    382 #else
    383 #define MAYBE_DragDropInSingleViewTest DragDropInSingleViewTest
    384 #endif
    385 TEST_F(DragDropControllerTest, MAYBE_DragDropInSingleViewTest) {
    386   scoped_ptr<views::Widget> widget(CreateNewWidget());
    387   DragTestView* drag_view = new DragTestView;
    388   AddViewToWidgetAndResize(widget.get(), drag_view);
    389   ui::OSExchangeData data;
    390   data.SetString(UTF8ToUTF16("I am being dragged"));
    391   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    392                                        widget->GetNativeView());
    393   generator.PressLeftButton();
    394 
    395   int num_drags = 17;
    396   SetCheckIfCaptureLost(widget.get(), true);
    397   for (int i = 0; i < num_drags; ++i) {
    398     // Because we are not doing a blocking drag and drop, the original
    399     // OSDragExchangeData object is lost as soon as we return from the drag
    400     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    401     // drag_data_ to a fake drag data object that we created.
    402     if (i > 0)
    403       UpdateDragData(&data);
    404     // 7 comes from views::View::GetVerticalDragThreshold()).
    405     if (i >= 7)
    406       SetCheckIfCaptureLost(widget.get(), false);
    407 
    408     generator.MoveMouseBy(0, 1);
    409 
    410     // Execute any scheduled draws to process deferred mouse events.
    411     RunAllPendingInMessageLoop();
    412   }
    413 
    414   generator.ReleaseLeftButton();
    415 
    416   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    417   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    418       drag_drop_controller_->num_drag_updates_);
    419   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    420   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    421       drag_drop_controller_->drag_string_);
    422 
    423   EXPECT_EQ(1, drag_view->num_drag_enters_);
    424   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    425       drag_view->num_drag_updates_);
    426   EXPECT_EQ(1, drag_view->num_drops_);
    427   EXPECT_EQ(0, drag_view->num_drag_exits_);
    428   EXPECT_TRUE(drag_view->drag_done_received_);
    429 }
    430 
    431 TEST_F(DragDropControllerTest, DragDropWithZeroDragUpdates) {
    432   scoped_ptr<views::Widget> widget(CreateNewWidget());
    433   DragTestView* drag_view = new DragTestView;
    434   AddViewToWidgetAndResize(widget.get(), drag_view);
    435   ui::OSExchangeData data;
    436   data.SetString(UTF8ToUTF16("I am being dragged"));
    437   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    438                                        widget->GetNativeView());
    439   generator.PressLeftButton();
    440 
    441   int num_drags = drag_view->VerticalDragThreshold() + 1;
    442   for (int i = 0; i < num_drags; ++i) {
    443     // Because we are not doing a blocking drag and drop, the original
    444     // OSDragExchangeData object is lost as soon as we return from the drag
    445     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    446     // drag_data_ to a fake drag data object that we created.
    447     if (i > 0)
    448       UpdateDragData(&data);
    449     generator.MoveMouseBy(0, 1);
    450   }
    451 
    452   UpdateDragData(&data);
    453 
    454   generator.ReleaseLeftButton();
    455 
    456   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    457   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold() + 1,
    458       drag_drop_controller_->num_drag_updates_);
    459   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    460 
    461   EXPECT_EQ(1, drag_view->num_drag_enters_);
    462   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold() + 1,
    463       drag_view->num_drag_updates_);
    464   EXPECT_EQ(1, drag_view->num_drops_);
    465   EXPECT_EQ(0, drag_view->num_drag_exits_);
    466   EXPECT_TRUE(drag_view->drag_done_received_);
    467 }
    468 
    469 // TODO(win_aura) http://crbug.com/154081
    470 #if defined(OS_WIN)
    471 #define MAYBE_DragDropInMultipleViewsSingleWidgetTest DISABLED_DragDropInMultipleViewsSingleWidgetTest
    472 #else
    473 #define MAYBE_DragDropInMultipleViewsSingleWidgetTest DragDropInMultipleViewsSingleWidgetTest
    474 #endif
    475 TEST_F(DragDropControllerTest, MAYBE_DragDropInMultipleViewsSingleWidgetTest) {
    476   scoped_ptr<views::Widget> widget(CreateNewWidget());
    477   DragTestView* drag_view1 = new DragTestView;
    478   AddViewToWidgetAndResize(widget.get(), drag_view1);
    479   DragTestView* drag_view2 = new DragTestView;
    480   AddViewToWidgetAndResize(widget.get(), drag_view2);
    481 
    482   ui::OSExchangeData data;
    483   data.SetString(UTF8ToUTF16("I am being dragged"));
    484 
    485   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
    486   generator.MoveMouseRelativeTo(widget->GetNativeView(),
    487                                 drag_view1->bounds().CenterPoint());
    488   generator.PressLeftButton();
    489 
    490   int num_drags = drag_view1->width();
    491   for (int i = 0; i < num_drags; ++i) {
    492     // Because we are not doing a blocking drag and drop, the original
    493     // OSDragExchangeData object is lost as soon as we return from the drag
    494     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    495     // drag_data_ to a fake drag data object that we created.
    496     if (i > 0)
    497       UpdateDragData(&data);
    498     generator.MoveMouseBy(1, 0);
    499 
    500     // Execute any scheduled draws to process deferred mouse events.
    501     RunAllPendingInMessageLoop();
    502   }
    503 
    504   generator.ReleaseLeftButton();
    505 
    506   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    507   EXPECT_EQ(num_drags - 1 - drag_view1->HorizontalDragThreshold(),
    508       drag_drop_controller_->num_drag_updates_);
    509   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    510   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    511       drag_drop_controller_->drag_string_);
    512 
    513   EXPECT_EQ(1, drag_view1->num_drag_enters_);
    514   int num_expected_updates = drag_view1->bounds().width() -
    515       drag_view1->bounds().CenterPoint().x() - 2;
    516   EXPECT_EQ(num_expected_updates - drag_view1->HorizontalDragThreshold(),
    517       drag_view1->num_drag_updates_);
    518   EXPECT_EQ(0, drag_view1->num_drops_);
    519   EXPECT_EQ(1, drag_view1->num_drag_exits_);
    520   EXPECT_TRUE(drag_view1->drag_done_received_);
    521 
    522   EXPECT_EQ(1, drag_view2->num_drag_enters_);
    523   num_expected_updates = num_drags - num_expected_updates - 1;
    524   EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_);
    525   EXPECT_EQ(1, drag_view2->num_drops_);
    526   EXPECT_EQ(0, drag_view2->num_drag_exits_);
    527   EXPECT_FALSE(drag_view2->drag_done_received_);
    528 }
    529 
    530 // TODO(win_aura) http://crbug.com/154081
    531 #if defined(OS_WIN)
    532 #define MAYBE_DragDropInMultipleViewsMultipleWidgetsTest DISABLED_DragDropInMultipleViewsMultipleWidgetsTest
    533 #else
    534 #define MAYBE_DragDropInMultipleViewsMultipleWidgetsTest DragDropInMultipleViewsMultipleWidgetsTest
    535 #endif
    536 TEST_F(DragDropControllerTest, MAYBE_DragDropInMultipleViewsMultipleWidgetsTest) {
    537   scoped_ptr<views::Widget> widget1(CreateNewWidget());
    538   DragTestView* drag_view1 = new DragTestView;
    539   AddViewToWidgetAndResize(widget1.get(), drag_view1);
    540   scoped_ptr<views::Widget> widget2(CreateNewWidget());
    541   DragTestView* drag_view2 = new DragTestView;
    542   AddViewToWidgetAndResize(widget2.get(), drag_view2);
    543   gfx::Rect widget1_bounds = widget1->GetClientAreaBoundsInScreen();
    544   gfx::Rect widget2_bounds = widget2->GetClientAreaBoundsInScreen();
    545   widget2->SetBounds(gfx::Rect(widget1_bounds.width(), 0,
    546       widget2_bounds.width(), widget2_bounds.height()));
    547 
    548   ui::OSExchangeData data;
    549   data.SetString(UTF8ToUTF16("I am being dragged"));
    550 
    551   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    552                                        widget1->GetNativeView());
    553   generator.PressLeftButton();
    554 
    555   int num_drags = drag_view1->width();
    556   for (int i = 0; i < num_drags; ++i) {
    557     // Because we are not doing a blocking drag and drop, the original
    558     // OSDragExchangeData object is lost as soon as we return from the drag
    559     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    560     // drag_data_ to a fake drag data object that we created.
    561     if (i > 0)
    562       UpdateDragData(&data);
    563     generator.MoveMouseBy(1, 0);
    564 
    565     // Execute any scheduled draws to process deferred mouse events.
    566     RunAllPendingInMessageLoop();
    567   }
    568 
    569   generator.ReleaseLeftButton();
    570 
    571   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    572   EXPECT_EQ(num_drags - 1 - drag_view1->HorizontalDragThreshold(),
    573       drag_drop_controller_->num_drag_updates_);
    574   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    575   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    576       drag_drop_controller_->drag_string_);
    577 
    578   EXPECT_EQ(1, drag_view1->num_drag_enters_);
    579   int num_expected_updates = drag_view1->bounds().width() -
    580       drag_view1->bounds().CenterPoint().x() - 2;
    581   EXPECT_EQ(num_expected_updates - drag_view1->HorizontalDragThreshold(),
    582       drag_view1->num_drag_updates_);
    583   EXPECT_EQ(0, drag_view1->num_drops_);
    584   EXPECT_EQ(1, drag_view1->num_drag_exits_);
    585   EXPECT_TRUE(drag_view1->drag_done_received_);
    586 
    587   EXPECT_EQ(1, drag_view2->num_drag_enters_);
    588   num_expected_updates = num_drags - num_expected_updates - 1;
    589   EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_);
    590   EXPECT_EQ(1, drag_view2->num_drops_);
    591   EXPECT_EQ(0, drag_view2->num_drag_exits_);
    592   EXPECT_FALSE(drag_view2->drag_done_received_);
    593 }
    594 
    595 // TODO(win_aura) http://crbug.com/154081
    596 #if defined(OS_WIN)
    597 #define MAYBE_ViewRemovedWhileInDragDropTest DISABLED_ViewRemovedWhileInDragDropTest
    598 #else
    599 #define MAYBE_ViewRemovedWhileInDragDropTest ViewRemovedWhileInDragDropTest
    600 #endif
    601 TEST_F(DragDropControllerTest, MAYBE_ViewRemovedWhileInDragDropTest) {
    602   scoped_ptr<views::Widget> widget(CreateNewWidget());
    603   scoped_ptr<DragTestView> drag_view(new DragTestView);
    604   AddViewToWidgetAndResize(widget.get(), drag_view.get());
    605   gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
    606   ui::OSExchangeData data;
    607   data.SetString(UTF8ToUTF16("I am being dragged"));
    608 
    609   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
    610   generator.MoveMouseToCenterOf(widget->GetNativeView());
    611   generator.PressLeftButton();
    612 
    613   int num_drags_1 = 17;
    614   for (int i = 0; i < num_drags_1; ++i) {
    615     // Because we are not doing a blocking drag and drop, the original
    616     // OSDragExchangeData object is lost as soon as we return from the drag
    617     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    618     // drag_data_ to a fake drag data object that we created.
    619     if (i > 0)
    620       UpdateDragData(&data);
    621     generator.MoveMouseBy(0, 1);
    622 
    623     // Execute any scheduled draws to process deferred mouse events.
    624     RunAllPendingInMessageLoop();
    625   }
    626 
    627   drag_view->parent()->RemoveChildView(drag_view.get());
    628   // View has been removed. We will not get any of the following drag updates.
    629   int num_drags_2 = 23;
    630   for (int i = 0; i < num_drags_2; ++i) {
    631     UpdateDragData(&data);
    632     generator.MoveMouseBy(0, 1);
    633 
    634     // Execute any scheduled draws to process deferred mouse events.
    635     RunAllPendingInMessageLoop();
    636   }
    637 
    638   generator.ReleaseLeftButton();
    639 
    640   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    641   EXPECT_EQ(num_drags_1 + num_drags_2 - 1 - drag_view->VerticalDragThreshold(),
    642       drag_drop_controller_->num_drag_updates_);
    643   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    644   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    645       drag_drop_controller_->drag_string_);
    646 
    647   EXPECT_EQ(1, drag_view->num_drag_enters_);
    648   EXPECT_EQ(num_drags_1 - 1 - drag_view->VerticalDragThreshold(),
    649       drag_view->num_drag_updates_);
    650   EXPECT_EQ(0, drag_view->num_drops_);
    651   EXPECT_EQ(0, drag_view->num_drag_exits_);
    652   EXPECT_TRUE(drag_view->drag_done_received_);
    653 }
    654 
    655 TEST_F(DragDropControllerTest, DragLeavesClipboardAloneTest) {
    656   ui::Clipboard* cb = ui::Clipboard::GetForCurrentThread();
    657   std::string clip_str("I am on the clipboard");
    658   {
    659     // We first copy some text to the clipboard.
    660     ui::ScopedClipboardWriter scw(cb, ui::Clipboard::BUFFER_STANDARD);
    661     scw.WriteText(ASCIIToUTF16(clip_str));
    662   }
    663   EXPECT_TRUE(cb->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
    664       ui::Clipboard::BUFFER_STANDARD));
    665 
    666   scoped_ptr<views::Widget> widget(CreateNewWidget());
    667   DragTestView* drag_view = new DragTestView;
    668   AddViewToWidgetAndResize(widget.get(), drag_view);
    669 
    670   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    671                                        widget->GetNativeView());
    672   ui::OSExchangeData data;
    673   std::string data_str("I am being dragged");
    674   data.SetString(ASCIIToUTF16(data_str));
    675 
    676   generator.PressLeftButton();
    677   generator.MoveMouseBy(0, drag_view->VerticalDragThreshold() + 1);
    678 
    679   // Execute any scheduled draws to process deferred mouse events.
    680   RunAllPendingInMessageLoop();
    681 
    682   // Verify the clipboard contents haven't changed
    683   std::string result;
    684   EXPECT_TRUE(cb->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(),
    685       ui::Clipboard::BUFFER_STANDARD));
    686   cb->ReadAsciiText(ui::Clipboard::BUFFER_STANDARD, &result);
    687   EXPECT_EQ(clip_str, result);
    688   // Destory the clipboard here because ash doesn't delete it.
    689   // crbug.com/158150.
    690   ui::Clipboard::DestroyClipboardForCurrentThread();
    691 }
    692 
    693 TEST_F(DragDropControllerTest, WindowDestroyedDuringDragDrop) {
    694   scoped_ptr<views::Widget> widget(CreateNewWidget());
    695   DragTestView* drag_view = new DragTestView;
    696   AddViewToWidgetAndResize(widget.get(), drag_view);
    697   aura::Window* window = widget->GetNativeView();
    698 
    699   ui::OSExchangeData data;
    700   data.SetString(UTF8ToUTF16("I am being dragged"));
    701   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    702                                        widget->GetNativeView());
    703   generator.PressLeftButton();
    704 
    705   int num_drags = 17;
    706   for (int i = 0; i < num_drags; ++i) {
    707     // Because we are not doing a blocking drag and drop, the original
    708     // OSDragExchangeData object is lost as soon as we return from the drag
    709     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    710     // drag_data_ to a fake drag data object that we created.
    711     if (i > 0)
    712       UpdateDragData(&data);
    713     generator.MoveMouseBy(0, 1);
    714 
    715     // Execute any scheduled draws to process deferred mouse events.
    716     RunAllPendingInMessageLoop();
    717 
    718     if (i > drag_view->VerticalDragThreshold())
    719       EXPECT_EQ(window, GetDragWindow());
    720   }
    721 
    722   widget->CloseNow();
    723   EXPECT_FALSE(GetDragWindow());
    724 
    725   num_drags = 23;
    726   for (int i = 0; i < num_drags; ++i) {
    727     if (i > 0)
    728       UpdateDragData(&data);
    729     generator.MoveMouseBy(0, 1);
    730     // We should not crash here.
    731   }
    732 
    733   generator.ReleaseLeftButton();
    734 
    735   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    736   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    737 }
    738 
    739 TEST_F(DragDropControllerTest, SyntheticEventsDuringDragDrop) {
    740   scoped_ptr<views::Widget> widget(CreateNewWidget());
    741   DragTestView* drag_view = new DragTestView;
    742   AddViewToWidgetAndResize(widget.get(), drag_view);
    743   ui::OSExchangeData data;
    744   data.SetString(UTF8ToUTF16("I am being dragged"));
    745   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    746                                        widget->GetNativeView());
    747   generator.PressLeftButton();
    748 
    749   int num_drags = 17;
    750   for (int i = 0; i < num_drags; ++i) {
    751     // Because we are not doing a blocking drag and drop, the original
    752     // OSDragExchangeData object is lost as soon as we return from the drag
    753     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    754     // drag_data_ to a fake drag data object that we created.
    755     if (i > 0)
    756       UpdateDragData(&data);
    757     generator.MoveMouseBy(0, 1);
    758 
    759     // We send a unexpected mouse move event. Note that we cannot use
    760     // EventGenerator since it implicitly turns these into mouse drag events.
    761     // The DragDropController should simply ignore these events.
    762     gfx::Point mouse_move_location = drag_view->bounds().CenterPoint();
    763     ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, mouse_move_location,
    764                               mouse_move_location, 0);
    765     Shell::GetPrimaryRootWindow()->AsRootWindowHostDelegate()->OnHostMouseEvent(
    766         &mouse_move);
    767   }
    768 
    769   generator.ReleaseLeftButton();
    770 
    771   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    772   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    773       drag_drop_controller_->num_drag_updates_);
    774   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    775   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    776       drag_drop_controller_->drag_string_);
    777 
    778   EXPECT_EQ(1, drag_view->num_drag_enters_);
    779   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    780       drag_view->num_drag_updates_);
    781   EXPECT_EQ(1, drag_view->num_drops_);
    782   EXPECT_EQ(0, drag_view->num_drag_exits_);
    783   EXPECT_TRUE(drag_view->drag_done_received_);
    784 }
    785 
    786 // TODO(win_aura) http://crbug.com/154081
    787 #if defined(OS_WIN)
    788 #define MAYBE_PressingEscapeCancelsDragDrop DISABLED_PressingEscapeCancelsDragDrop
    789 #define MAYBE_CaptureLostCancelsDragDrop DISABLED_CaptureLostCancelsDragDrop
    790 #else
    791 #define MAYBE_PressingEscapeCancelsDragDrop PressingEscapeCancelsDragDrop
    792 #define MAYBE_CaptureLostCancelsDragDrop CaptureLostCancelsDragDrop
    793 #endif
    794 TEST_F(DragDropControllerTest, MAYBE_PressingEscapeCancelsDragDrop) {
    795   scoped_ptr<views::Widget> widget(CreateNewWidget());
    796   DragTestView* drag_view = new DragTestView;
    797   AddViewToWidgetAndResize(widget.get(), drag_view);
    798   ui::OSExchangeData data;
    799   data.SetString(UTF8ToUTF16("I am being dragged"));
    800   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    801                                        widget->GetNativeView());
    802   generator.PressLeftButton();
    803 
    804   int num_drags = 17;
    805   for (int i = 0; i < num_drags; ++i) {
    806     // Because we are not doing a blocking drag and drop, the original
    807     // OSDragExchangeData object is lost as soon as we return from the drag
    808     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    809     // drag_data_ to a fake drag data object that we created.
    810     if (i > 0)
    811       UpdateDragData(&data);
    812     generator.MoveMouseBy(0, 1);
    813 
    814     // Execute any scheduled draws to process deferred mouse events.
    815     RunAllPendingInMessageLoop();
    816   }
    817 
    818   generator.PressKey(ui::VKEY_ESCAPE, 0);
    819 
    820   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    821   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    822       drag_drop_controller_->num_drag_updates_);
    823   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    824   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    825   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    826       drag_drop_controller_->drag_string_);
    827 
    828   EXPECT_EQ(1, drag_view->num_drag_enters_);
    829   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    830       drag_view->num_drag_updates_);
    831   EXPECT_EQ(0, drag_view->num_drops_);
    832   EXPECT_EQ(1, drag_view->num_drag_exits_);
    833   EXPECT_TRUE(drag_view->drag_done_received_);
    834 }
    835 
    836 TEST_F(DragDropControllerTest, MAYBE_CaptureLostCancelsDragDrop) {
    837   scoped_ptr<views::Widget> widget(CreateNewWidget());
    838   DragTestView* drag_view = new DragTestView;
    839   AddViewToWidgetAndResize(widget.get(), drag_view);
    840   ui::OSExchangeData data;
    841   data.SetString(UTF8ToUTF16("I am being dragged"));
    842   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    843                                        widget->GetNativeView());
    844   generator.PressLeftButton();
    845 
    846   int num_drags = 17;
    847   for (int i = 0; i < num_drags; ++i) {
    848     // Because we are not doing a blocking drag and drop, the original
    849     // OSDragExchangeData object is lost as soon as we return from the drag
    850     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    851     // drag_data_ to a fake drag data object that we created.
    852     if (i > 0)
    853       UpdateDragData(&data);
    854     generator.MoveMouseBy(0, 1);
    855 
    856     // Execute any scheduled draws to process deferred mouse events.
    857     RunAllPendingInMessageLoop();
    858   }
    859   // Make sure the capture window won't handle mouse events.
    860   aura::Window* capture_window = drag_drop_tracker()->capture_window();
    861   ASSERT_TRUE(!!capture_window);
    862   EXPECT_EQ("0x0", capture_window->bounds().size().ToString());
    863   EXPECT_EQ(NULL,
    864             capture_window->GetEventHandlerForPoint(gfx::Point()));
    865   EXPECT_EQ(NULL,
    866             capture_window->GetTopWindowContainingPoint(gfx::Point()));
    867 
    868   aura::client::GetCaptureClient(widget->GetNativeView()->GetRootWindow())->
    869       SetCapture(NULL);
    870 
    871   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    872   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    873       drag_drop_controller_->num_drag_updates_);
    874   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    875   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    876   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    877       drag_drop_controller_->drag_string_);
    878 
    879   EXPECT_EQ(1, drag_view->num_drag_enters_);
    880   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    881       drag_view->num_drag_updates_);
    882   EXPECT_EQ(0, drag_view->num_drops_);
    883   EXPECT_EQ(1, drag_view->num_drag_exits_);
    884   EXPECT_TRUE(drag_view->drag_done_received_);
    885 }
    886 
    887 TEST_F(DragDropControllerTest, TouchDragDropInMultipleWindows) {
    888   CommandLine::ForCurrentProcess()->AppendSwitch(
    889       switches::kEnableTouchDragDrop);
    890   scoped_ptr<views::Widget> widget1(CreateNewWidget());
    891   DragTestView* drag_view1 = new DragTestView;
    892   AddViewToWidgetAndResize(widget1.get(), drag_view1);
    893   scoped_ptr<views::Widget> widget2(CreateNewWidget());
    894   DragTestView* drag_view2 = new DragTestView;
    895   AddViewToWidgetAndResize(widget2.get(), drag_view2);
    896   gfx::Rect widget1_bounds = widget1->GetClientAreaBoundsInScreen();
    897   gfx::Rect widget2_bounds = widget2->GetClientAreaBoundsInScreen();
    898   widget2->SetBounds(gfx::Rect(widget1_bounds.width(), 0,
    899       widget2_bounds.width(), widget2_bounds.height()));
    900 
    901   ui::OSExchangeData data;
    902   data.SetString(UTF8ToUTF16("I am being dragged"));
    903 
    904   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    905                                        widget1->GetNativeView());
    906   generator.PressTouch();
    907   gfx::Point point = gfx::Rect(drag_view1->bounds()).CenterPoint();
    908   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    909   // Because we are not doing a blocking drag and drop, the original
    910   // OSDragExchangeData object is lost as soon as we return from the drag
    911   // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    912   // drag_data_ to a fake drag data object that we created.
    913   UpdateDragData(&data);
    914   gfx::Point gesture_location = point;
    915   int num_drags = drag_view1->width();
    916   for (int i = 0; i < num_drags; ++i) {
    917     gesture_location.Offset(1, 0);
    918     DispatchGesture(ui::ET_GESTURE_SCROLL_UPDATE, gesture_location);
    919 
    920     // Execute any scheduled draws to process deferred mouse events.
    921     RunAllPendingInMessageLoop();
    922   }
    923 
    924   DispatchGesture(ui::ET_GESTURE_SCROLL_END, gesture_location);
    925 
    926   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    927   EXPECT_EQ(num_drags, drag_drop_controller_->num_drag_updates_);
    928   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    929   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    930       drag_drop_controller_->drag_string_);
    931 
    932   EXPECT_EQ(1, drag_view1->num_drag_enters_);
    933   int num_expected_updates = drag_view1->bounds().width() -
    934       drag_view1->bounds().CenterPoint().x() - 1;
    935   EXPECT_EQ(num_expected_updates, drag_view1->num_drag_updates_);
    936   EXPECT_EQ(0, drag_view1->num_drops_);
    937   EXPECT_EQ(1, drag_view1->num_drag_exits_);
    938   EXPECT_TRUE(drag_view1->drag_done_received_);
    939 
    940   EXPECT_EQ(1, drag_view2->num_drag_enters_);
    941   num_expected_updates = num_drags - num_expected_updates;
    942   EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_);
    943   EXPECT_EQ(1, drag_view2->num_drops_);
    944   EXPECT_EQ(0, drag_view2->num_drag_exits_);
    945   EXPECT_FALSE(drag_view2->drag_done_received_);
    946 }
    947 
    948 TEST_F(DragDropControllerTest, TouchDragDropCancelsOnLongTap) {
    949   CommandLine::ForCurrentProcess()->AppendSwitch(
    950       switches::kEnableTouchDragDrop);
    951   scoped_ptr<views::Widget> widget(CreateNewWidget());
    952   DragTestView* drag_view = new DragTestView;
    953   AddViewToWidgetAndResize(widget.get(), drag_view);
    954   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    955                                        widget->GetNativeView());
    956 
    957   generator.PressTouch();
    958   gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
    959   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    960   DispatchGesture(ui::ET_GESTURE_LONG_TAP, point);
    961 
    962   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    963   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    964   EXPECT_EQ(0, drag_drop_controller_->num_drag_updates_);
    965   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    966   EXPECT_EQ(UTF8ToUTF16("I am being dragged"),
    967             drag_drop_controller_->drag_string_);
    968   EXPECT_EQ(0, drag_view->num_drag_enters_);
    969   EXPECT_EQ(0, drag_view->num_drops_);
    970   EXPECT_EQ(0, drag_view->num_drag_exits_);
    971   EXPECT_TRUE(drag_view->drag_done_received_);
    972 }
    973 
    974 TEST_F(DragDropControllerTest, TouchDragDropLongTapGestureIsForwarded) {
    975   CommandLine::ForCurrentProcess()->AppendSwitch(
    976       switches::kEnableTouchDragDrop);
    977   scoped_ptr<views::Widget> widget(CreateNewWidget());
    978   DragTestView* drag_view = new DragTestView;
    979   AddViewToWidgetAndResize(widget.get(), drag_view);
    980   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    981                                        widget->GetNativeView());
    982 
    983   generator.PressTouch();
    984   gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
    985   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    986 
    987   // Since we are not running inside a nested loop, the |drag_source_window_|
    988   // will get destroyed immediately. Hence we reassign it.
    989   EXPECT_EQ(NULL, GetDragSourceWindow());
    990   SetDragSourceWindow(widget->GetNativeView());
    991   EXPECT_FALSE(drag_view->long_tap_received_);
    992   DispatchGesture(ui::ET_GESTURE_LONG_TAP, point);
    993   CompleteCancelAnimation();
    994   EXPECT_TRUE(drag_view->long_tap_received_);
    995 }
    996 
    997 namespace {
    998 
    999 class DragImageWindowObserver : public aura::WindowObserver {
   1000  public:
   1001   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
   1002     window_location_on_destroying_ = window->GetBoundsInScreen().origin();
   1003   }
   1004 
   1005   gfx::Point window_location_on_destroying() const {
   1006     return window_location_on_destroying_;
   1007   }
   1008 
   1009  public:
   1010   gfx::Point window_location_on_destroying_;
   1011 };
   1012 
   1013 }
   1014 
   1015 // Verifies the drag image moves back to the position where drag is started
   1016 // across displays when drag is cancelled.
   1017 TEST_F(DragDropControllerTest, DragCancelAcrossDisplays) {
   1018   if (!SupportsMultipleDisplays())
   1019     return;
   1020 
   1021   UpdateDisplay("400x400,400x400");
   1022   Shell::RootWindowList root_windows =
   1023       Shell::GetInstance()->GetAllRootWindows();
   1024   for (Shell::RootWindowList::iterator iter = root_windows.begin();
   1025        iter != root_windows.end(); ++iter) {
   1026     aura::client::SetDragDropClient(*iter, drag_drop_controller_.get());
   1027   }
   1028 
   1029   ui::OSExchangeData data;
   1030   data.SetString(UTF8ToUTF16("I am being dragged"));
   1031   {
   1032     scoped_ptr<views::Widget> widget(CreateNewWidget());
   1033     aura::Window* window = widget->GetNativeWindow();
   1034     drag_drop_controller_->StartDragAndDrop(
   1035         data,
   1036         window->GetRootWindow(),
   1037         window,
   1038         gfx::Point(5, 5),
   1039         ui::DragDropTypes::DRAG_MOVE,
   1040         ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
   1041 
   1042     DragImageWindowObserver observer;
   1043     ASSERT_TRUE(GetDragImageWindow());
   1044     GetDragImageWindow()->AddObserver(&observer);
   1045 
   1046     {
   1047       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1048                        gfx::Point(200, 0),
   1049                        gfx::Point(200, 0),
   1050                        ui::EF_NONE);
   1051       drag_drop_controller_->DragUpdate(window, e);
   1052     }
   1053     {
   1054       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1055                        gfx::Point(600, 0),
   1056                        gfx::Point(600, 0),
   1057                        ui::EF_NONE);
   1058       drag_drop_controller_->DragUpdate(window, e);
   1059     }
   1060 
   1061     drag_drop_controller_->DragCancel();
   1062     CompleteCancelAnimation();
   1063 
   1064     EXPECT_EQ("5,5", observer.window_location_on_destroying().ToString());
   1065   }
   1066 
   1067   {
   1068     scoped_ptr<views::Widget> widget(CreateNewWidget());
   1069     aura::Window* window = widget->GetNativeWindow();
   1070     drag_drop_controller_->StartDragAndDrop(
   1071         data,
   1072         window->GetRootWindow(),
   1073         window,
   1074         gfx::Point(405, 405),
   1075         ui::DragDropTypes::DRAG_MOVE,
   1076         ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
   1077     DragImageWindowObserver observer;
   1078     ASSERT_TRUE(GetDragImageWindow());
   1079     GetDragImageWindow()->AddObserver(&observer);
   1080 
   1081     {
   1082       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1083                        gfx::Point(600, 0),
   1084                        gfx::Point(600, 0),
   1085                        ui::EF_NONE);
   1086       drag_drop_controller_->DragUpdate(window, e);
   1087     }
   1088     {
   1089       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1090                        gfx::Point(200, 0),
   1091                        gfx::Point(200, 0),
   1092                        ui::EF_NONE);
   1093       drag_drop_controller_->DragUpdate(window, e);
   1094     }
   1095 
   1096     drag_drop_controller_->DragCancel();
   1097     CompleteCancelAnimation();
   1098 
   1099     EXPECT_EQ("405,405", observer.window_location_on_destroying().ToString());
   1100   }
   1101   for (Shell::RootWindowList::iterator iter = root_windows.begin();
   1102        iter != root_windows.end(); ++iter) {
   1103     aura::client::SetDragDropClient(*iter, NULL);
   1104   }
   1105 }
   1106 
   1107 }  // namespace test
   1108 }  // namespace aura
   1109