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/test/event_generator.h"
     16 #include "ui/aura/window_event_dispatcher.h"
     17 #include "ui/aura/window_tree_host.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/ui_base_switches.h"
     24 #include "ui/events/event.h"
     25 #include "ui/events/event_utils.h"
     26 #include "ui/events/gestures/gesture_types.h"
     27 #include "ui/events/test/events_test_utils.h"
     28 #include "ui/gfx/animation/linear_animation.h"
     29 #include "ui/gfx/image/image_skia_rep.h"
     30 #include "ui/views/view.h"
     31 #include "ui/views/views_delegate.h"
     32 #include "ui/views/widget/native_widget_aura.h"
     33 #include "ui/views/widget/native_widget_delegate.h"
     34 #include "ui/views/widget/widget.h"
     35 
     36 namespace ash {
     37 namespace test {
     38 
     39 namespace {
     40 
     41 // A simple view that makes sure RunShellDrag is invoked on mouse drag.
     42 class DragTestView : public views::View {
     43  public:
     44   DragTestView() : views::View() {
     45     Reset();
     46   }
     47 
     48   void Reset() {
     49     num_drag_enters_ = 0;
     50     num_drag_exits_ = 0;
     51     num_drag_updates_ = 0;
     52     num_drops_ = 0;
     53     drag_done_received_ = false;
     54     long_tap_received_ = false;
     55   }
     56 
     57   int VerticalDragThreshold() {
     58     return views::View::GetVerticalDragThreshold();
     59   }
     60 
     61   int HorizontalDragThreshold() {
     62     return views::View::GetHorizontalDragThreshold();
     63   }
     64 
     65   int num_drag_enters_;
     66   int num_drag_exits_;
     67   int num_drag_updates_;
     68   int num_drops_;
     69   bool drag_done_received_;
     70   bool long_tap_received_;
     71 
     72  private:
     73   // View overrides:
     74   virtual int GetDragOperations(const gfx::Point& press_pt) OVERRIDE {
     75     return ui::DragDropTypes::DRAG_COPY;
     76   }
     77 
     78   virtual void WriteDragData(const gfx::Point& p,
     79                              OSExchangeData* data) OVERRIDE {
     80     data->SetString(base::UTF8ToUTF16("I am being dragged"));
     81     gfx::ImageSkiaRep image_rep(gfx::Size(10, 20), 1.0f);
     82     gfx::ImageSkia image_skia(image_rep);
     83 
     84     drag_utils::SetDragImageOnDataObject(image_skia, 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 DragDropController {
    151  public:
    152   TestDragDropController() : DragDropController() { Reset(); }
    153 
    154   void Reset() {
    155     drag_start_received_ = false;
    156     num_drag_updates_ = 0;
    157     drop_received_ = false;
    158     drag_canceled_ = false;
    159     drag_string_.clear();
    160   }
    161 
    162   virtual int StartDragAndDrop(
    163       const ui::OSExchangeData& data,
    164       aura::Window* root_window,
    165       aura::Window* source_window,
    166       const gfx::Point& location,
    167       int operation,
    168       ui::DragDropTypes::DragEventSource source) OVERRIDE {
    169     drag_start_received_ = true;
    170     data.GetString(&drag_string_);
    171     return DragDropController::StartDragAndDrop(
    172         data, root_window, source_window, location, operation, source);
    173   }
    174 
    175   virtual void DragUpdate(aura::Window* target,
    176                           const ui::LocatedEvent& event) OVERRIDE {
    177     DragDropController::DragUpdate(target, event);
    178     num_drag_updates_++;
    179   }
    180 
    181   virtual void Drop(aura::Window* target,
    182                     const ui::LocatedEvent& event) OVERRIDE {
    183     DragDropController::Drop(target, event);
    184     drop_received_ = true;
    185   }
    186 
    187   virtual void DragCancel() OVERRIDE {
    188     DragDropController::DragCancel();
    189     drag_canceled_ = true;
    190   }
    191 
    192   virtual gfx::LinearAnimation* CreateCancelAnimation(
    193       int duration,
    194       int frame_rate,
    195       gfx::AnimationDelegate* delegate) OVERRIDE {
    196     return new CompletableLinearAnimation(duration, frame_rate, delegate);
    197   }
    198 
    199   virtual void DoDragCancel(int animation_duration_ms) OVERRIDE {
    200     DragDropController::DoDragCancel(animation_duration_ms);
    201     drag_canceled_ = true;
    202   }
    203 
    204   bool drag_start_received_;
    205   int num_drag_updates_;
    206   bool drop_received_;
    207   bool drag_canceled_;
    208   base::string16 drag_string_;
    209 
    210  private:
    211   DISALLOW_COPY_AND_ASSIGN(TestDragDropController);
    212 };
    213 
    214 class TestNativeWidgetAura : public views::NativeWidgetAura {
    215  public:
    216   explicit TestNativeWidgetAura(views::internal::NativeWidgetDelegate* delegate)
    217       : NativeWidgetAura(delegate),
    218         check_if_capture_lost_(false) {
    219   }
    220 
    221   void set_check_if_capture_lost(bool value) {
    222     check_if_capture_lost_ = value;
    223   }
    224 
    225   virtual void OnCaptureLost() OVERRIDE {
    226     DCHECK(!check_if_capture_lost_);
    227     views::NativeWidgetAura::OnCaptureLost();
    228   }
    229 
    230  private:
    231   bool check_if_capture_lost_;
    232 
    233   DISALLOW_COPY_AND_ASSIGN(TestNativeWidgetAura);
    234 };
    235 
    236 // TODO(sky): this is for debugging, remove when track down failure.
    237 void SetCheckIfCaptureLost(views::Widget* widget, bool value) {
    238   // On Windows, the DCHECK triggers when running on bot or locally through RDP,
    239   // but not when logged in locally.
    240 #if !defined(OS_WIN)
    241   static_cast<TestNativeWidgetAura*>(widget->native_widget())->
    242       set_check_if_capture_lost(value);
    243 #endif
    244 }
    245 
    246 views::Widget* CreateNewWidget() {
    247   views::Widget* widget = new views::Widget;
    248   views::Widget::InitParams params;
    249   params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
    250   params.accept_events = true;
    251   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    252   params.parent = Shell::GetPrimaryRootWindow();
    253   params.child = true;
    254   params.native_widget = new TestNativeWidgetAura(widget);
    255   widget->Init(params);
    256   widget->Show();
    257   return widget;
    258 }
    259 
    260 void AddViewToWidgetAndResize(views::Widget* widget, views::View* view) {
    261   if (!widget->GetContentsView()) {
    262     views::View* contents_view = new views::View;
    263     widget->SetContentsView(contents_view);
    264   }
    265 
    266   views::View* contents_view = widget->GetContentsView();
    267   contents_view->AddChildView(view);
    268   view->SetBounds(contents_view->width(), 0, 100, 100);
    269   gfx::Rect contents_view_bounds = contents_view->bounds();
    270   contents_view_bounds.Union(view->bounds());
    271   contents_view->SetBoundsRect(contents_view_bounds);
    272   widget->SetBounds(contents_view_bounds);
    273 }
    274 
    275 void DispatchGesture(ui::EventType gesture_type, gfx::Point location) {
    276   ui::GestureEvent gesture_event(
    277       gesture_type,
    278       location.x(),
    279       location.y(),
    280       0,
    281       ui::EventTimeForNow(),
    282       ui::GestureEventDetails(gesture_type, 0, 0),
    283       1);
    284   ui::EventSource* event_source =
    285       Shell::GetPrimaryRootWindow()->GetHost()->GetEventSource();
    286   ui::EventSourceTestApi event_source_test(event_source);
    287   ui::EventDispatchDetails details =
    288       event_source_test.SendEventToProcessor(&gesture_event);
    289   CHECK(!details.dispatcher_destroyed);
    290 }
    291 
    292 }  // namespace
    293 
    294 class DragDropControllerTest : public AshTestBase {
    295  public:
    296   DragDropControllerTest() : AshTestBase() {}
    297   virtual ~DragDropControllerTest() {}
    298 
    299   virtual void SetUp() OVERRIDE {
    300     AshTestBase::SetUp();
    301     drag_drop_controller_.reset(new TestDragDropController);
    302     drag_drop_controller_->set_should_block_during_drag_drop(false);
    303     aura::client::SetDragDropClient(Shell::GetPrimaryRootWindow(),
    304                                     drag_drop_controller_.get());
    305   }
    306 
    307   virtual void TearDown() OVERRIDE {
    308     aura::client::SetDragDropClient(Shell::GetPrimaryRootWindow(), NULL);
    309     drag_drop_controller_.reset();
    310     AshTestBase::TearDown();
    311   }
    312 
    313   void UpdateDragData(ui::OSExchangeData* data) {
    314     drag_drop_controller_->drag_data_ = data;
    315   }
    316 
    317   aura::Window* GetDragWindow() {
    318     return drag_drop_controller_->drag_window_;
    319   }
    320 
    321   aura::Window* GetDragSourceWindow() {
    322     return drag_drop_controller_->drag_source_window_;
    323   }
    324 
    325   void SetDragSourceWindow(aura::Window* drag_source_window) {
    326     drag_drop_controller_->drag_source_window_ = drag_source_window;
    327     drag_source_window->AddObserver(drag_drop_controller_.get());
    328   }
    329 
    330   aura::Window* GetDragImageWindow() {
    331     return drag_drop_controller_->drag_image_.get() ?
    332         drag_drop_controller_->drag_image_->GetWidget()->GetNativeWindow() :
    333         NULL;
    334   }
    335 
    336   DragDropTracker* drag_drop_tracker() {
    337     return drag_drop_controller_->drag_drop_tracker_.get();
    338   }
    339 
    340   void CompleteCancelAnimation() {
    341     CompletableLinearAnimation* animation =
    342         static_cast<CompletableLinearAnimation*>(
    343             drag_drop_controller_->cancel_animation_.get());
    344     animation->Complete();
    345   }
    346 
    347  protected:
    348   scoped_ptr<TestDragDropController> drag_drop_controller_;
    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(base::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(base::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(base::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(base::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(base::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(base::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(base::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(base::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(base::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(base::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(base::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(base::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(base::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, 0);
    740     ui::EventDispatchDetails details = Shell::GetPrimaryRootWindow()->
    741         GetHost()->event_processor()->OnEventFromSource(&mouse_move);
    742     ASSERT_FALSE(details.dispatcher_destroyed);
    743   }
    744 
    745   generator.ReleaseLeftButton();
    746 
    747   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    748   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    749       drag_drop_controller_->num_drag_updates_);
    750   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    751   EXPECT_EQ(base::UTF8ToUTF16("I am being dragged"),
    752       drag_drop_controller_->drag_string_);
    753 
    754   EXPECT_EQ(1, drag_view->num_drag_enters_);
    755   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    756       drag_view->num_drag_updates_);
    757   EXPECT_EQ(1, drag_view->num_drops_);
    758   EXPECT_EQ(0, drag_view->num_drag_exits_);
    759   EXPECT_TRUE(drag_view->drag_done_received_);
    760 }
    761 
    762 // TODO(win_aura) http://crbug.com/154081
    763 #if defined(OS_WIN)
    764 #define MAYBE_PressingEscapeCancelsDragDrop DISABLED_PressingEscapeCancelsDragDrop
    765 #define MAYBE_CaptureLostCancelsDragDrop DISABLED_CaptureLostCancelsDragDrop
    766 #else
    767 #define MAYBE_PressingEscapeCancelsDragDrop PressingEscapeCancelsDragDrop
    768 #define MAYBE_CaptureLostCancelsDragDrop CaptureLostCancelsDragDrop
    769 #endif
    770 TEST_F(DragDropControllerTest, MAYBE_PressingEscapeCancelsDragDrop) {
    771   scoped_ptr<views::Widget> widget(CreateNewWidget());
    772   DragTestView* drag_view = new DragTestView;
    773   AddViewToWidgetAndResize(widget.get(), drag_view);
    774   ui::OSExchangeData data;
    775   data.SetString(base::UTF8ToUTF16("I am being dragged"));
    776   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    777                                        widget->GetNativeView());
    778   generator.PressLeftButton();
    779 
    780   int num_drags = 17;
    781   for (int i = 0; i < num_drags; ++i) {
    782     // Because we are not doing a blocking drag and drop, the original
    783     // OSDragExchangeData object is lost as soon as we return from the drag
    784     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    785     // drag_data_ to a fake drag data object that we created.
    786     if (i > 0)
    787       UpdateDragData(&data);
    788     generator.MoveMouseBy(0, 1);
    789 
    790     // Execute any scheduled draws to process deferred mouse events.
    791     RunAllPendingInMessageLoop();
    792   }
    793 
    794   generator.PressKey(ui::VKEY_ESCAPE, 0);
    795 
    796   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    797   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    798       drag_drop_controller_->num_drag_updates_);
    799   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    800   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    801   EXPECT_EQ(base::UTF8ToUTF16("I am being dragged"),
    802       drag_drop_controller_->drag_string_);
    803 
    804   EXPECT_EQ(1, drag_view->num_drag_enters_);
    805   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    806       drag_view->num_drag_updates_);
    807   EXPECT_EQ(0, drag_view->num_drops_);
    808   EXPECT_EQ(1, drag_view->num_drag_exits_);
    809   EXPECT_TRUE(drag_view->drag_done_received_);
    810 }
    811 
    812 TEST_F(DragDropControllerTest, MAYBE_CaptureLostCancelsDragDrop) {
    813   scoped_ptr<views::Widget> widget(CreateNewWidget());
    814   DragTestView* drag_view = new DragTestView;
    815   AddViewToWidgetAndResize(widget.get(), drag_view);
    816   ui::OSExchangeData data;
    817   data.SetString(base::UTF8ToUTF16("I am being dragged"));
    818   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    819                                        widget->GetNativeView());
    820   generator.PressLeftButton();
    821 
    822   int num_drags = 17;
    823   for (int i = 0; i < num_drags; ++i) {
    824     // Because we are not doing a blocking drag and drop, the original
    825     // OSDragExchangeData object is lost as soon as we return from the drag
    826     // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    827     // drag_data_ to a fake drag data object that we created.
    828     if (i > 0)
    829       UpdateDragData(&data);
    830     generator.MoveMouseBy(0, 1);
    831 
    832     // Execute any scheduled draws to process deferred mouse events.
    833     RunAllPendingInMessageLoop();
    834   }
    835   // Make sure the capture window won't handle mouse events.
    836   aura::Window* capture_window = drag_drop_tracker()->capture_window();
    837   ASSERT_TRUE(!!capture_window);
    838   EXPECT_EQ("0x0", capture_window->bounds().size().ToString());
    839   EXPECT_EQ(NULL,
    840             capture_window->GetEventHandlerForPoint(gfx::Point()));
    841   EXPECT_EQ(NULL,
    842             capture_window->GetTopWindowContainingPoint(gfx::Point()));
    843 
    844   aura::client::GetCaptureClient(widget->GetNativeView()->GetRootWindow())->
    845       SetCapture(NULL);
    846 
    847   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    848   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    849       drag_drop_controller_->num_drag_updates_);
    850   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    851   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    852   EXPECT_EQ(base::UTF8ToUTF16("I am being dragged"),
    853       drag_drop_controller_->drag_string_);
    854 
    855   EXPECT_EQ(1, drag_view->num_drag_enters_);
    856   EXPECT_EQ(num_drags - 1 - drag_view->VerticalDragThreshold(),
    857       drag_view->num_drag_updates_);
    858   EXPECT_EQ(0, drag_view->num_drops_);
    859   EXPECT_EQ(1, drag_view->num_drag_exits_);
    860   EXPECT_TRUE(drag_view->drag_done_received_);
    861 }
    862 
    863 TEST_F(DragDropControllerTest, TouchDragDropInMultipleWindows) {
    864   CommandLine::ForCurrentProcess()->AppendSwitch(
    865       switches::kEnableTouchDragDrop);
    866   scoped_ptr<views::Widget> widget1(CreateNewWidget());
    867   DragTestView* drag_view1 = new DragTestView;
    868   AddViewToWidgetAndResize(widget1.get(), drag_view1);
    869   scoped_ptr<views::Widget> widget2(CreateNewWidget());
    870   DragTestView* drag_view2 = new DragTestView;
    871   AddViewToWidgetAndResize(widget2.get(), drag_view2);
    872   gfx::Rect widget1_bounds = widget1->GetClientAreaBoundsInScreen();
    873   gfx::Rect widget2_bounds = widget2->GetClientAreaBoundsInScreen();
    874   widget2->SetBounds(gfx::Rect(widget1_bounds.width(), 0,
    875       widget2_bounds.width(), widget2_bounds.height()));
    876 
    877   ui::OSExchangeData data;
    878   data.SetString(base::UTF8ToUTF16("I am being dragged"));
    879 
    880   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    881                                        widget1->GetNativeView());
    882   generator.PressTouch();
    883   gfx::Point point = gfx::Rect(drag_view1->bounds()).CenterPoint();
    884   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    885   // Because we are not doing a blocking drag and drop, the original
    886   // OSDragExchangeData object is lost as soon as we return from the drag
    887   // initiation in DragDropController::StartDragAndDrop(). Hence we set the
    888   // drag_data_ to a fake drag data object that we created.
    889   UpdateDragData(&data);
    890   gfx::Point gesture_location = point;
    891   int num_drags = drag_view1->width();
    892   for (int i = 0; i < num_drags; ++i) {
    893     gesture_location.Offset(1, 0);
    894     DispatchGesture(ui::ET_GESTURE_SCROLL_UPDATE, gesture_location);
    895 
    896     // Execute any scheduled draws to process deferred mouse events.
    897     RunAllPendingInMessageLoop();
    898   }
    899 
    900   DispatchGesture(ui::ET_GESTURE_SCROLL_END, gesture_location);
    901 
    902   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    903   EXPECT_EQ(num_drags, drag_drop_controller_->num_drag_updates_);
    904   EXPECT_TRUE(drag_drop_controller_->drop_received_);
    905   EXPECT_EQ(base::UTF8ToUTF16("I am being dragged"),
    906       drag_drop_controller_->drag_string_);
    907 
    908   EXPECT_EQ(1, drag_view1->num_drag_enters_);
    909   int num_expected_updates = drag_view1->bounds().width() -
    910       drag_view1->bounds().CenterPoint().x() - 1;
    911   EXPECT_EQ(num_expected_updates, drag_view1->num_drag_updates_);
    912   EXPECT_EQ(0, drag_view1->num_drops_);
    913   EXPECT_EQ(1, drag_view1->num_drag_exits_);
    914   EXPECT_TRUE(drag_view1->drag_done_received_);
    915 
    916   EXPECT_EQ(1, drag_view2->num_drag_enters_);
    917   num_expected_updates = num_drags - num_expected_updates;
    918   EXPECT_EQ(num_expected_updates, drag_view2->num_drag_updates_);
    919   EXPECT_EQ(1, drag_view2->num_drops_);
    920   EXPECT_EQ(0, drag_view2->num_drag_exits_);
    921   EXPECT_FALSE(drag_view2->drag_done_received_);
    922 }
    923 
    924 TEST_F(DragDropControllerTest, TouchDragDropCancelsOnLongTap) {
    925   CommandLine::ForCurrentProcess()->AppendSwitch(
    926       switches::kEnableTouchDragDrop);
    927   scoped_ptr<views::Widget> widget(CreateNewWidget());
    928   DragTestView* drag_view = new DragTestView;
    929   AddViewToWidgetAndResize(widget.get(), drag_view);
    930   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    931                                        widget->GetNativeView());
    932 
    933   generator.PressTouch();
    934   gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
    935   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    936   DispatchGesture(ui::ET_GESTURE_LONG_TAP, point);
    937 
    938   EXPECT_TRUE(drag_drop_controller_->drag_start_received_);
    939   EXPECT_TRUE(drag_drop_controller_->drag_canceled_);
    940   EXPECT_EQ(0, drag_drop_controller_->num_drag_updates_);
    941   EXPECT_FALSE(drag_drop_controller_->drop_received_);
    942   EXPECT_EQ(base::UTF8ToUTF16("I am being dragged"),
    943             drag_drop_controller_->drag_string_);
    944   EXPECT_EQ(0, drag_view->num_drag_enters_);
    945   EXPECT_EQ(0, drag_view->num_drops_);
    946   EXPECT_EQ(0, drag_view->num_drag_exits_);
    947   EXPECT_TRUE(drag_view->drag_done_received_);
    948 }
    949 
    950 TEST_F(DragDropControllerTest, TouchDragDropLongTapGestureIsForwarded) {
    951   CommandLine::ForCurrentProcess()->AppendSwitch(
    952       switches::kEnableTouchDragDrop);
    953   scoped_ptr<views::Widget> widget(CreateNewWidget());
    954   DragTestView* drag_view = new DragTestView;
    955   AddViewToWidgetAndResize(widget.get(), drag_view);
    956   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow(),
    957                                        widget->GetNativeView());
    958 
    959   generator.PressTouch();
    960   gfx::Point point = gfx::Rect(drag_view->bounds()).CenterPoint();
    961   DispatchGesture(ui::ET_GESTURE_LONG_PRESS, point);
    962 
    963   // Since we are not running inside a nested loop, the |drag_source_window_|
    964   // will get destroyed immediately. Hence we reassign it.
    965   EXPECT_EQ(NULL, GetDragSourceWindow());
    966   SetDragSourceWindow(widget->GetNativeView());
    967   EXPECT_FALSE(drag_view->long_tap_received_);
    968   DispatchGesture(ui::ET_GESTURE_LONG_TAP, point);
    969   CompleteCancelAnimation();
    970   EXPECT_TRUE(drag_view->long_tap_received_);
    971 }
    972 
    973 namespace {
    974 
    975 class DragImageWindowObserver : public aura::WindowObserver {
    976  public:
    977   virtual void OnWindowDestroying(aura::Window* window) OVERRIDE {
    978     window_location_on_destroying_ = window->GetBoundsInScreen().origin();
    979   }
    980 
    981   gfx::Point window_location_on_destroying() const {
    982     return window_location_on_destroying_;
    983   }
    984 
    985  public:
    986   gfx::Point window_location_on_destroying_;
    987 };
    988 
    989 }
    990 
    991 // Verifies the drag image moves back to the position where drag is started
    992 // across displays when drag is cancelled.
    993 TEST_F(DragDropControllerTest, DragCancelAcrossDisplays) {
    994   if (!SupportsMultipleDisplays())
    995     return;
    996 
    997   UpdateDisplay("400x400,400x400");
    998   aura::Window::Windows root_windows =
    999       Shell::GetInstance()->GetAllRootWindows();
   1000   for (aura::Window::Windows::iterator iter = root_windows.begin();
   1001        iter != root_windows.end(); ++iter) {
   1002     aura::client::SetDragDropClient(*iter, drag_drop_controller_.get());
   1003   }
   1004 
   1005   ui::OSExchangeData data;
   1006   data.SetString(base::UTF8ToUTF16("I am being dragged"));
   1007   {
   1008     scoped_ptr<views::Widget> widget(CreateNewWidget());
   1009     aura::Window* window = widget->GetNativeWindow();
   1010     drag_drop_controller_->StartDragAndDrop(
   1011         data,
   1012         window->GetRootWindow(),
   1013         window,
   1014         gfx::Point(5, 5),
   1015         ui::DragDropTypes::DRAG_MOVE,
   1016         ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
   1017 
   1018     DragImageWindowObserver observer;
   1019     ASSERT_TRUE(GetDragImageWindow());
   1020     GetDragImageWindow()->AddObserver(&observer);
   1021 
   1022     {
   1023       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1024                        gfx::Point(200, 0),
   1025                        gfx::Point(200, 0),
   1026                        ui::EF_NONE,
   1027                        ui::EF_NONE);
   1028       drag_drop_controller_->DragUpdate(window, e);
   1029     }
   1030     {
   1031       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1032                        gfx::Point(600, 0),
   1033                        gfx::Point(600, 0),
   1034                        ui::EF_NONE,
   1035                        ui::EF_NONE);
   1036       drag_drop_controller_->DragUpdate(window, e);
   1037     }
   1038 
   1039     drag_drop_controller_->DragCancel();
   1040     CompleteCancelAnimation();
   1041 
   1042     EXPECT_EQ("5,5", observer.window_location_on_destroying().ToString());
   1043   }
   1044 
   1045   {
   1046     scoped_ptr<views::Widget> widget(CreateNewWidget());
   1047     aura::Window* window = widget->GetNativeWindow();
   1048     drag_drop_controller_->StartDragAndDrop(
   1049         data,
   1050         window->GetRootWindow(),
   1051         window,
   1052         gfx::Point(405, 405),
   1053         ui::DragDropTypes::DRAG_MOVE,
   1054         ui::DragDropTypes::DRAG_EVENT_SOURCE_MOUSE);
   1055     DragImageWindowObserver observer;
   1056     ASSERT_TRUE(GetDragImageWindow());
   1057     GetDragImageWindow()->AddObserver(&observer);
   1058 
   1059     {
   1060       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1061                        gfx::Point(600, 0),
   1062                        gfx::Point(600, 0),
   1063                        ui::EF_NONE,
   1064                        ui::EF_NONE);
   1065       drag_drop_controller_->DragUpdate(window, e);
   1066     }
   1067     {
   1068       ui::MouseEvent e(ui::ET_MOUSE_DRAGGED,
   1069                        gfx::Point(200, 0),
   1070                        gfx::Point(200, 0),
   1071                        ui::EF_NONE,
   1072                        ui::EF_NONE);
   1073       drag_drop_controller_->DragUpdate(window, e);
   1074     }
   1075 
   1076     drag_drop_controller_->DragCancel();
   1077     CompleteCancelAnimation();
   1078 
   1079     EXPECT_EQ("405,405", observer.window_location_on_destroying().ToString());
   1080   }
   1081   for (aura::Window::Windows::iterator iter = root_windows.begin();
   1082        iter != root_windows.end(); ++iter) {
   1083     aura::client::SetDragDropClient(*iter, NULL);
   1084   }
   1085 }
   1086 
   1087 }  // namespace test
   1088 }  // namespace aura
   1089