// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>
#include <initializer_list>
#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/pattern.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_timeouts.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/test_frame_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "net/base/escape.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/drag_drop_client.h"
#include "ui/aura/client/drag_drop_delegate.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/window.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"
#include "url/gurl.h"

namespace chrome {

namespace {

// TODO(lukasza): Support testing on non-Aura platforms (i.e. Android + Mac?).
//
// Notes for the TODO above:
//
// - Why inject/simulate drag-and-drop events at the aura::Window* level.
//
//   - It seems better to inject into UI libraries to cover code *inside* these
//     libraries.  This might complicate simulation a little bit (i.e. picking
//     the right aura::Window and/or aura::client::DragDropDelegate to target),
//     but otherwise important bits of code wouldn't get test coverage (i.e.
//     directly injecting into RenderViewHost->DragTargetDragEnter seems wrong).
//
//   - In theory, we could introduce WebContentsImpl::DragTargetDragEnter (to be
//     used by all UI platforms - so reused by web_contents_view_android.cc,
//     web_contents_view_aura.cc, web_drag_dest_mac.mm), but it feels wrong - UI
//     libraries should already know which widget is the target of the event and
//     so should be able to talk directly to the right widget (i.e. WebContents
//     should not be responsible for mapping coordinates to a widget - this is
//     the job of the UI library).
//
// - Unknowns:
//
//   - Will this work for WebView and Plugin testing.

// Test helper for simulating drag and drop happening in WebContents.
class DragAndDropSimulator {
 public:
  explicit DragAndDropSimulator(content::WebContents* web_contents)
      : web_contents_(web_contents) {}

  // Simulates notification that |text| was dragged from outside of the browser,
  // into the specified |location| inside |web_contents|.
  // |location| is relative to |web_contents|.
  // Returns true upon success.
  bool SimulateDragEnter(gfx::Point location, const std::string& text) {
    os_exchange_data_ = std::make_unique<ui::OSExchangeData>();
    os_exchange_data_->SetString(base::UTF8ToUTF16(text));
    return SimulateDragEnter(location, *os_exchange_data_);
  }

  // Simulates dropping of the drag-and-dropped item.
  // SimulateDragEnter needs to be called first.
  // Returns true upon success.
  bool SimulateDrop(gfx::Point location) {
    if (!active_drag_event_) {
      ADD_FAILURE() << "Cannot drop a drag that hasn't started yet.";
      return false;
    }

    aura::client::DragDropDelegate* delegate = GetDragDropDelegate();
    if (!delegate)
      return false;

    gfx::PointF event_location;
    gfx::PointF event_root_location;
    CalculateEventLocations(location, &event_location, &event_root_location);
    active_drag_event_->set_location_f(event_location);
    active_drag_event_->set_root_location_f(event_root_location);

    delegate->OnDragUpdated(*active_drag_event_);
    delegate->OnPerformDrop(*active_drag_event_);
    return true;
  }

 private:
  bool SimulateDragEnter(gfx::Point location, const ui::OSExchangeData& data) {
    if (active_drag_event_) {
      ADD_FAILURE() << "Cannot start a new drag when old one hasn't ended yet.";
      return false;
    }

    aura::client::DragDropDelegate* delegate = GetDragDropDelegate();
    if (!delegate)
      return false;

    gfx::PointF event_location;
    gfx::PointF event_root_location;
    CalculateEventLocations(location, &event_location, &event_root_location);
    active_drag_event_.reset(new ui::DropTargetEvent(
        data, event_location, event_root_location, kDefaultSourceOperations));

    delegate->OnDragEntered(*active_drag_event_);
    delegate->OnDragUpdated(*active_drag_event_);
    return true;
  }

  aura::client::DragDropDelegate* GetDragDropDelegate() {
    gfx::NativeView view = web_contents_->GetContentNativeView();
    aura::client::DragDropDelegate* delegate =
        aura::client::GetDragDropDelegate(view);
    EXPECT_TRUE(delegate) << "Expecting WebContents to have DragDropDelegate";
    return delegate;
  }

  void CalculateEventLocations(gfx::Point web_contents_relative_location,
                               gfx::PointF* out_event_location,
                               gfx::PointF* out_event_root_location) {
    gfx::NativeView view = web_contents_->GetNativeView();

    *out_event_location = gfx::PointF(web_contents_relative_location);

    gfx::Point root_location = web_contents_relative_location;
    aura::Window::ConvertPointToTarget(view, view->GetRootWindow(),
                                       &root_location);
    *out_event_root_location = gfx::PointF(root_location);
  }

  // These are ui::DropTargetEvent::source_operations_ being sent when manually
  // trying out drag&drop of an image file from Nemo (Ubuntu's file explorer)
  // into a content_shell.
  static constexpr int kDefaultSourceOperations = ui::DragDropTypes::DRAG_MOVE |
                                                  ui::DragDropTypes::DRAG_COPY |
                                                  ui::DragDropTypes::DRAG_LINK;

  content::WebContents* web_contents_;
  std::unique_ptr<ui::DropTargetEvent> active_drag_event_;
  std::unique_ptr<ui::OSExchangeData> os_exchange_data_;

  DISALLOW_COPY_AND_ASSIGN(DragAndDropSimulator);
};

// Helper for waiting until a drag-and-drop starts (e.g. in response to a
// mouse-down + mouse-move simulated by the test).
class DragStartWaiter : public aura::client::DragDropClient {
 public:
  // Starts monitoring |web_contents| for a start of a drag-and-drop.
  explicit DragStartWaiter(content::WebContents* web_contents)
      : web_contents_(web_contents),
        message_loop_runner_(new content::MessageLoopRunner),
        suppress_passing_of_start_drag_further_(false),
        drag_started_(false) {
    DCHECK(web_contents_);

    // Intercept calls to the old DragDropClient.
    gfx::NativeWindow root_window =
        web_contents_->GetContentNativeView()->GetRootWindow();
    old_client_ = aura::client::GetDragDropClient(root_window);
    aura::client::SetDragDropClient(root_window, this);
  }

  ~DragStartWaiter() override {
    // Restore the original DragDropClient.
    gfx::NativeWindow root_window =
        web_contents_->GetContentNativeView()->GetRootWindow();
    aura::client::SetDragDropClient(root_window, old_client_);
  }

  // Waits until we almost report a drag-and-drop start to the OS.
  // At that point
  // 1) the callback from PostTaskWhenDragStarts will be posted.
  // 2) the drag-start request will be forwarded to the OS
  //    (unless SuppressPassingStartDragFurther method was called).
  //
  // Note that if SuppressPassingStartDragFurther was not called then
  // WaitUntilDragStart can take a long time to return (it returns only after
  // the OS decides that the drag-and-drop has ended).
  //
  // Before returning populates |text|, |html| and other parameters with data
  // that would have been passed to the OS).  If the caller is not interested in
  // this data, then the corresponding argument can be null.
  void WaitUntilDragStart(std::string* text,
                          std::string* html,
                          int* operation,
                          gfx::Point* location_inside_web_contents) {
    message_loop_runner_->Run();

    // message_loop_runner_->Quit is only called from StartDragAndDrop.
    DCHECK(drag_started_);

    if (text)
      *text = text_;
    if (html)
      *html = html_;
    if (operation)
      *operation = operation_;
    if (location_inside_web_contents)
      *location_inside_web_contents = location_inside_web_contents_;
  }

  void SuppressPassingStartDragFurther() {
    suppress_passing_of_start_drag_further_ = true;
  }

  void PostTaskWhenDragStarts(const base::Closure& callback) {
    callback_to_run_inside_drag_and_drop_message_loop_ = callback;
  }

  // aura::client::DragDropClient overrides:
  int StartDragAndDrop(const ui::OSExchangeData& data,
                       aura::Window* root_window,
                       aura::Window* source_window,
                       const gfx::Point& screen_location,
                       int operation,
                       ui::DragDropTypes::DragEventSource source) override {
    DCHECK(!drag_started_);
    if (!drag_started_) {
      drag_started_ = true;
      message_loop_runner_->Quit();

      base::string16 text;
      if (data.GetString(&text))
        text_ = base::UTF16ToUTF8(text);
      else
        text_ = "<no text>";

      GURL base_url;
      base::string16 html;
      if (data.GetHtml(&html, &base_url))
        html_ = base::UTF16ToUTF8(html);
      else
        html_ = "<no html>";

      gfx::Rect bounds =
          web_contents_->GetContentNativeView()->GetBoundsInScreen();
      location_inside_web_contents_ =
          screen_location - gfx::Vector2d(bounds.x(), bounds.y());

      operation_ = operation;
    }

    if (!callback_to_run_inside_drag_and_drop_message_loop_.is_null()) {
      base::SequencedTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          std::move(callback_to_run_inside_drag_and_drop_message_loop_));
      callback_to_run_inside_drag_and_drop_message_loop_.Reset();
    }

    if (suppress_passing_of_start_drag_further_)
      return 0;

    // Start a nested drag-and-drop loop (might not return for a long time).
    return old_client_->StartDragAndDrop(data, root_window, source_window,
                                         screen_location, operation, source);
  }

  void DragCancel() override {
    ADD_FAILURE() << "Unexpected call to DragCancel";
  }

  bool IsDragDropInProgress() override { return drag_started_; }

  void AddObserver(aura::client::DragDropClientObserver* observer) override {}
  void RemoveObserver(aura::client::DragDropClientObserver* observer) override {
  }

 private:
  content::WebContents* web_contents_;
  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
  aura::client::DragDropClient* old_client_;
  base::Closure callback_to_run_inside_drag_and_drop_message_loop_;
  bool suppress_passing_of_start_drag_further_;

  // Data captured during the first intercepted StartDragAndDrop call.
  bool drag_started_;
  std::string text_;
  std::string html_;
  int operation_;
  gfx::Point location_inside_web_contents_;

  DISALLOW_COPY_AND_ASSIGN(DragStartWaiter);
};

// Helper for waiting for notifications from
// content/test/data/drag_and_drop/event_monitoring.js
class DOMDragEventWaiter {
 public:
  DOMDragEventWaiter(const std::string& event_type_to_wait_for,
                     const content::ToRenderFrameHost& target)
      : target_frame_name_(target.render_frame_host()->GetFrameName()),
        event_type_to_wait_for_(event_type_to_wait_for),
        dom_message_queue_(content::WebContents::FromRenderFrameHost(
            target.render_frame_host())) {}

  // Waits until |target| calls reportDragEvent in
  // chrome/test/data/drag_and_drop/event_monitoring.js with event_type
  // property set to |event_type_to_wait_for|.  (|target| and
  // |event_type_to_wait_for| are passed to the constructor).
  //
  // Returns the event details via |found_event| (in form of a JSON-encoded
  // object).  See chrome/test/data/drag_and_drop/event_monitoring.js for keys
  // and properties that |found_event| is expected to have.
  //
  // Returns true upon success.  It is okay if |response| is null.
  bool WaitForNextMatchingEvent(std::string* found_event) WARN_UNUSED_RESULT {
    std::string candidate_event;
    bool got_right_event_type = false;
    bool got_right_window_name = false;
    do {
      if (!dom_message_queue_.WaitForMessage(&candidate_event))
        return false;

      got_right_event_type =
          IsExpectedEventType(candidate_event, event_type_to_wait_for_);
      got_right_window_name =
          IsExpectedWindowName(candidate_event, target_frame_name_);
    } while (!got_right_event_type || !got_right_window_name);

    if (found_event)
      *found_event = candidate_event;

    return true;
  }

  static bool IsExpectedEventType(const std::string& actual_event_body,
                                  const std::string& expected_event_type) {
    return IsExpectedPropertyValue(actual_event_body, "event_type",
                                   expected_event_type);
  }

  static bool IsExpectedWindowName(const std::string& actual_event_body,
                                   const std::string& expected_window_name) {
    return IsExpectedPropertyValue(actual_event_body, "window_name",
                                   expected_window_name);
  }

 private:
  static bool IsExpectedPropertyValue(
      const std::string& actual_event_body,
      const std::string& property_name,
      const std::string& expected_property_value) {
    return base::MatchPattern(
        actual_event_body,
        base::StringPrintf("*\"%s\":\"%s\"*", property_name.c_str(),
                           expected_property_value.c_str()));
  }

  std::string target_frame_name_;
  std::string event_type_to_wait_for_;
  content::DOMMessageQueue dom_message_queue_;

  DISALLOW_COPY_AND_ASSIGN(DOMDragEventWaiter);
};

// Helper for verifying contents of DOM events associated with drag-and-drop.
class DOMDragEventVerifier {
 public:
  DOMDragEventVerifier() {}

  void set_expected_client_position(const std::string& value) {
    expected_client_position_ = value;
  }

  void set_expected_drop_effect(const std::string& value) {
    expected_drop_effect_ = value;
  }

  void set_expected_effect_allowed(const std::string& value) {
    expected_effect_allowed_ = value;
  }

  void set_expected_mime_types(const std::string& value) {
    expected_mime_types_ = value;
  }

  void set_expected_page_position(const std::string& value) {
    expected_page_position_ = value;
  }

  void set_expected_screen_position(const std::string& value) {
    expected_screen_position_ = value;
  }

  // Returns a matcher that will match a std::string (drag event data - e.g.
  // one returned by DOMDragEventWaiter::WaitForNextMatchingEvent) if it matches
  // the expectations of this DOMDragEventVerifier.
  testing::Matcher<std::string> Matches() const {
    return testing::AllOf(
        FieldMatches("client_position", expected_client_position_),
        FieldMatches("drop_effect", expected_drop_effect_),
        FieldMatches("effect_allowed", expected_effect_allowed_),
        FieldMatches("mime_types", expected_mime_types_),
        FieldMatches("page_position", expected_page_position_),
        FieldMatches("screen_position", expected_screen_position_));
  }

 private:
  static testing::Matcher<std::string> FieldMatches(
      const std::string& field_name,
      const std::string& expected_value) {
    if (expected_value == "<no expectation>")
      return testing::A<std::string>();

    return testing::HasSubstr(base::StringPrintf(
        "\"%s\":\"%s\"", field_name.c_str(), expected_value.c_str()));
  }

  std::string expected_drop_effect_ = "<no expectation>";
  std::string expected_effect_allowed_ = "<no expectation>";
  std::string expected_mime_types_ = "<no expectation>";
  std::string expected_client_position_ = "<no expectation>";
  std::string expected_page_position_ = "<no expectation>";
  std::string expected_screen_position_ = "<no expectation>";

  DISALLOW_COPY_AND_ASSIGN(DOMDragEventVerifier);
};

// Helper for monitoring event notifications from
// content/test/data/drag_and_drop/event_monitoring.js
// and counting how many events of a given type were received.
class DOMDragEventCounter {
 public:
  explicit DOMDragEventCounter(const content::ToRenderFrameHost& target)
      : target_frame_name_(target.render_frame_host()->GetFrameName()),
        dom_message_queue_(content::WebContents::FromRenderFrameHost(
            target.render_frame_host())) {}

  // Resets all the accumulated event counts to zeros.
  void Reset() {
    StoreAccumulatedEvents();
    received_events_.clear();
  }

  // Returns the number of events of the specified |event_type| received since
  // construction, or since the last time Reset was called.  |event_type| should
  // be one of possible |type| property values for a DOM drag-and-drop event -
  // e.g.  "dragenter" or "dragover".
  int GetNumberOfReceivedEvents(const std::string& event_type) {
    std::vector<std::string> v({event_type});
    return GetNumberOfReceivedEvents(v.begin(), v.end());
  }

  // Returns the number of events of the specified |event_types| received since
  // construction, or since the last time Reset was called.  Elements of
  // |event_types| should be one of possible |type| property values for a DOM
  // drag-and-drop event - e.g.  "dragenter" or "dragover".
  int GetNumberOfReceivedEvents(
      std::initializer_list<const char*> event_types) {
    return GetNumberOfReceivedEvents(event_types.begin(), event_types.end());
  }

 private:
  template <typename T>
  int GetNumberOfReceivedEvents(T event_types_begin, T event_types_end) {
    StoreAccumulatedEvents();

    auto received_event_has_matching_event_type =
        [&event_types_begin,
         &event_types_end](const std::string& received_event) {
          return std::any_of(event_types_begin, event_types_end,
                             [&received_event](const std::string& event_type) {
                               return DOMDragEventWaiter::IsExpectedEventType(
                                   received_event, event_type);
                             });
        };

    return std::count_if(received_events_.begin(), received_events_.end(),
                         received_event_has_matching_event_type);
  }

  void StoreAccumulatedEvents() {
    std::string candidate_event;
    while (dom_message_queue_.PopMessage(&candidate_event)) {
      if (DOMDragEventWaiter::IsExpectedWindowName(candidate_event,
                                                   target_frame_name_)) {
        received_events_.push_back(candidate_event);
      }
    }
  }

  std::string target_frame_name_;
  content::DOMMessageQueue dom_message_queue_;
  std::vector<std::string> received_events_;

  DISALLOW_COPY_AND_ASSIGN(DOMDragEventCounter);
};

const char kTestPagePath[] = "/drag_and_drop/page.html";

}  // namespace

class DragAndDropBrowserTest : public InProcessBrowserTest,
                               public testing::WithParamInterface<bool> {
 public:
  DragAndDropBrowserTest() {}

  struct DragImageBetweenFrames_TestState;
  void DragImageBetweenFrames_Step2(DragImageBetweenFrames_TestState*);
  void DragImageBetweenFrames_Step3(DragImageBetweenFrames_TestState*);

  struct DragImageFromDisappearingFrame_TestState;
  void DragImageFromDisappearingFrame_Step2(
      DragImageFromDisappearingFrame_TestState*);
  void DragImageFromDisappearingFrame_Step3(
      DragImageFromDisappearingFrame_TestState*);

  struct CrossSiteDrag_TestState;
  void CrossSiteDrag_Step2(CrossSiteDrag_TestState*);
  void CrossSiteDrag_Step3(CrossSiteDrag_TestState*);

 protected:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    content::SetupCrossSiteRedirector(embedded_test_server());
    ASSERT_TRUE(embedded_test_server()->Start());
    drag_simulator_.reset(new DragAndDropSimulator(web_contents()));
  }

  void TearDownOnMainThread() override {
    // For X11 need to tear down before UI goes away.
    drag_simulator_.reset();
  }

  bool use_cross_site_subframe() {
    // This is controlled by gtest's test param from INSTANTIATE_TEST_SUITE_P.
    return GetParam();
  }

  content::RenderFrameHost* left_frame() {
    AssertTestPageIsLoaded();
    return GetFrameByName("left");
  }

  content::RenderFrameHost* right_frame() {
    AssertTestPageIsLoaded();
    return GetFrameByName("right");
  }

  content::WebContents* web_contents() {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

  //////////////////////
  // Navigation helpers.

  bool NavigateToTestPage(const std::string& origin_of_main_frame) {
    GURL url =
        embedded_test_server()->GetURL(origin_of_main_frame, kTestPagePath);
    ui_test_utils::NavigateToURL(browser(), url);
    return web_contents()->GetLastCommittedURL() == url;
  }

  // Navigates the left frame to |filename| (found under
  // chrome/test/data/drag_and_drop directory).
  bool NavigateLeftFrame(const std::string& origin,
                         const std::string& filename) {
    AssertTestPageIsLoaded();
    return NavigateNamedFrame("left", origin, filename);
  }

  // Navigates the right frame to |filename| (found under
  // chrome/test/data/drag_and_drop directory).
  bool NavigateRightFrame(const std::string& origin,
                          const std::string& filename) {
    AssertTestPageIsLoaded();
    return NavigateNamedFrame("right", origin, filename);
  }

  ////////////////////////////////////////////////////////////
  // Simulation of starting a drag-and-drop (using the mouse).

  bool SimulateMouseDownAndDragStartInLeftFrame() {
    AssertTestPageIsLoaded();

    // Waiting until the mousemove and mousedown events reach the right renderer
    // is needed to avoid flakiness reported in https://crbug.com/671445 (which
    // has its root cause in https://crbug.com/647378).  Once the latter bug
    // is fixed, we should no longer need to wait for these events (because
    // fixing https://crbug.com/647378 should guarantee that events arrive
    // to the renderer in the right order).
    DOMDragEventWaiter mouse_move_event_waiter("mousemove", left_frame());
    DOMDragEventWaiter mouse_down_event_waiter("mousedown", left_frame());

    if (!SimulateMouseMove(kMiddleOfLeftFrame))
      return false;
    if (!mouse_move_event_waiter.WaitForNextMatchingEvent(nullptr))
      return false;

    if (!SimulateMouseDown())
      return false;
    if (!mouse_down_event_waiter.WaitForNextMatchingEvent(nullptr))
      return false;

    if (!SimulateMouseMove(expected_location_of_drag_start_in_left_frame()))
      return false;

    return true;
  }

  gfx::Point expected_location_of_drag_start_in_left_frame() {
    // TODO(crbug.com/653490): The delta below should exceed kDragThresholdX and
    // kDragThresholdY from MouseEventManager.cpp in blink.  Ideally, it would
    // come from the OS instead.
    return kMiddleOfLeftFrame + gfx::Vector2d(10, 10);
  }

  bool SimulateMouseMoveToLeftFrame() {
    AssertTestPageIsLoaded();
    return SimulateMouseMove(kMiddleOfLeftFrame);
  }

  bool SimulateMouseMoveToRightFrame() {
    AssertTestPageIsLoaded();
    return SimulateMouseMove(kMiddleOfRightFrame);
  }

  bool SimulateMouseUp() {
    return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
                                              ui_controls::UP);
  }

  ////////////////////////////////////////////////////////////////////
  // Simulation of dragging from outside the browser into web contents
  // (using DragAndDropSimulator, not simulating mouse events).

  bool SimulateDragEnterToRightFrame(const std::string& text) {
    AssertTestPageIsLoaded();
    return drag_simulator_->SimulateDragEnter(kMiddleOfRightFrame, text);
  }

  bool SimulateDropInRightFrame() {
    AssertTestPageIsLoaded();
    return drag_simulator_->SimulateDrop(kMiddleOfRightFrame);
  }

  gfx::Point GetMiddleOfRightFrameInScreenCoords() {
    aura::Window* window = web_contents()->GetNativeView();
    aura::client::ScreenPositionClient* screen_position_client =
        aura::client::GetScreenPositionClient(window->GetRootWindow());
    gfx::Point screen_position(kMiddleOfRightFrame);
    if (screen_position_client)
      screen_position_client->ConvertPointToScreen(window, &screen_position);
    return screen_position;
  }

 private:
  // Constants with coordinates within content/test/data/drag_and_drop/page.html
  // The precise frame center is at 200,200 and 400,200 coordinates, but slight
  // differences between left and right frame hopefully make it easier to detect
  // incorrect dom_drag_and_drop_event.clientX/Y values in test asserts.
  const gfx::Point kMiddleOfLeftFrame = gfx::Point(155, 150);
  const gfx::Point kMiddleOfRightFrame = gfx::Point(455, 250);

  bool SimulateMouseDown() {
    return ui_test_utils::SendMouseEventsSync(ui_controls::LEFT,
                                              ui_controls::DOWN);
  }

  bool SimulateMouseMove(const gfx::Point& location_inside_web_contents) {
    gfx::Rect bounds = web_contents()->GetContainerBounds();
    return ui_test_utils::SendMouseMoveSync(
        gfx::Point(bounds.x() + location_inside_web_contents.x(),
                   bounds.y() + location_inside_web_contents.y()));
  }

  bool NavigateNamedFrame(const std::string& frame_name,
                          const std::string& origin,
                          const std::string& filename) {
    content::RenderFrameHost* frame = GetFrameByName(frame_name);
    if (!frame)
      return false;

    std::string script;
    int response = 0;

    // Navigate the frame and wait for the load event.
    script = base::StringPrintf(
        "location.href = '/cross-site/%s/drag_and_drop/%s';\n"
        "setTimeout(function() { domAutomationController.send(42); }, 0);",
        origin.c_str(), filename.c_str());
    content::TestFrameNavigationObserver observer(frame);
    if (!content::ExecuteScriptAndExtractInt(frame, script, &response))
      return false;
    if (response != 42)
      return false;
    observer.Wait();

    // |frame| might have been swapped-out during a cross-site navigation,
    // therefore we need to get the current RenderFrameHost to work against
    // going forward.
    frame = GetFrameByName(frame_name);
    DCHECK(frame);

    // Wait until hit testing data is ready.
    WaitForHitTestDataOrChildSurfaceReady(frame);

    return true;
  }

  content::RenderFrameHost* GetFrameByName(const std::string& name_to_find) {
    return content::FrameMatchingPredicate(
        web_contents(), base::Bind(&content::FrameMatchesName, name_to_find));
  }

  void AssertTestPageIsLoaded() {
    ASSERT_EQ(kTestPagePath, web_contents()->GetLastCommittedURL().path());
  }

  std::unique_ptr<DragAndDropSimulator> drag_simulator_;

  DISALLOW_COPY_AND_ASSIGN(DragAndDropBrowserTest);
};

#if defined(OS_CHROMEOS)
// Flaky: https://crbug.com/835774
#define MAYBE_DropTextFromOutside DISABLED_DropTextFromOutside
#else
#define MAYBE_DropTextFromOutside DropTextFromOutside
#endif
// Scenario: drag text from outside the browser and drop to the right frame.
// Test coverage: dragover, drop DOM events.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DropTextFromOutside) {
  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));

  // Setup test expectations.
  DOMDragEventVerifier expected_dom_event_data;
  expected_dom_event_data.set_expected_client_position("(155, 150)");
  expected_dom_event_data.set_expected_drop_effect("none");
  expected_dom_event_data.set_expected_effect_allowed("all");
  expected_dom_event_data.set_expected_mime_types("text/plain");
  expected_dom_event_data.set_expected_page_position("(155, 150)");

  // Drag text from outside the browser into/over the right frame.
  {
    DOMDragEventWaiter dragover_waiter("dragover", right_frame());
    ASSERT_TRUE(SimulateDragEnterToRightFrame("Dragged test text"));

    std::string dragover_event;
    ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event));
    EXPECT_THAT(dragover_event, expected_dom_event_data.Matches());
  }

  // Drop into the right frame.
  {
    DOMDragEventWaiter drop_waiter("drop", right_frame());
    ASSERT_TRUE(SimulateDropInRightFrame());

    std::string drop_event;
    ASSERT_TRUE(drop_waiter.WaitForNextMatchingEvent(&drop_event));
    EXPECT_THAT(drop_event, expected_dom_event_data.Matches());
  }
}

#if defined(OS_CHROMEOS) || !defined(NDEBUG)
// Flaky: https://crbug.com/835774
#define MAYBE_DragStartInFrame DISABLED_DragStartInFrame
#else
#define MAYBE_DragStartInFrame DragStartInFrame
#endif
// Scenario: starting a drag in left frame
// Test coverage: dragstart DOM event, dragstart data passed to the OS.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DragStartInFrame) {
  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));

  // Setup test expectations.
  DOMDragEventVerifier expected_dom_event_data;
  expected_dom_event_data.set_expected_client_position("(55, 50)");
  expected_dom_event_data.set_expected_drop_effect("none");
  // (dragstart event handler in image_source.html is asking for "copy" only).
  expected_dom_event_data.set_expected_effect_allowed("copy");
  expected_dom_event_data.set_expected_page_position("(55, 50)");

  // TODO(lukasza): Figure out why the dragstart event
  // - lists "Files" on the mime types list,
  // - doesn't list "text/plain" on the mime types list.
  // (i.e. why expectations below differ from expectations for dragenter,
  // dragover, dragend and/or drop events in DragImageBetweenFrames test).
  expected_dom_event_data.set_expected_mime_types(
      "Files,text/html,text/uri-list");

  // Start the drag in the left frame.
  DragStartWaiter drag_start_waiter(web_contents());
  drag_start_waiter.SuppressPassingStartDragFurther();
  DOMDragEventWaiter dragstart_event_waiter("dragstart", left_frame());
  EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());

  // Verify Javascript event data.
  {
    std::string dragstart_event;
    EXPECT_TRUE(
        dragstart_event_waiter.WaitForNextMatchingEvent(&dragstart_event));
    EXPECT_THAT(dragstart_event, expected_dom_event_data.Matches());
  }

  // Verify data being passed to the OS.
  {
    std::string text;
    std::string html;
    int operation = 0;
    gfx::Point location_inside_web_contents;
    drag_start_waiter.WaitUntilDragStart(&text, &html, &operation,
                                         &location_inside_web_contents);
    EXPECT_EQ(embedded_test_server()->GetURL(frame_site,
                                             "/image_decoding/droids.jpg"),
              text);
    EXPECT_THAT(html,
                testing::MatchesRegex("<img .*src=\""
                                      "http://.*/image_decoding/droids.jpg"
                                      "\">"));
    EXPECT_EQ(expected_location_of_drag_start_in_left_frame(),
              location_inside_web_contents);
    EXPECT_EQ(ui::DragDropTypes::DRAG_COPY, operation);
  }

  // Try to leave everything in a clean state.
  SimulateMouseUp();
}

#if defined(OS_WIN)
// There is no known way to execute test-controlled tasks during
// a drag-and-drop loop run by Windows OS.
#define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
#elif defined(OS_CHROMEOS) || defined(OS_LINUX)
// Flakiness on CrOS tracked by https://crbug.com/835573.
#define MAYBE_DragImageBetweenFrames DISABLED_DragImageBetweenFrames
#else
#define MAYBE_DragImageBetweenFrames DragImageBetweenFrames
#endif

// Data that needs to be shared across multiple test steps below
// (i.e. across DragImageBetweenFrames_Step2 and DragImageBetweenFrames_Step3).
struct DragAndDropBrowserTest::DragImageBetweenFrames_TestState {
  DOMDragEventVerifier expected_dom_event_data;
  std::unique_ptr<DOMDragEventWaiter> dragstart_event_waiter;
  std::unique_ptr<DOMDragEventWaiter> drop_event_waiter;
  std::unique_ptr<DOMDragEventWaiter> dragend_event_waiter;
  std::unique_ptr<DOMDragEventCounter> left_frame_events_counter;
  std::unique_ptr<DOMDragEventCounter> right_frame_events_counter;
};

// Scenario: drag an image from the left into the right frame.
// Test coverage: dragleave, dragenter, dragover, dragend, drop DOM events.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_DragImageBetweenFrames) {
  // Note that drag and drop will not expose data across cross-site frames on
  // the same page - this is why the same |frame_site| is used below both for
  // the left and the right frame.  See also https://crbug.com/59081.
  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
  ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));

  // Setup test expectations.
  DragAndDropBrowserTest::DragImageBetweenFrames_TestState state;
  state.left_frame_events_counter.reset(new DOMDragEventCounter(left_frame()));
  state.right_frame_events_counter.reset(
      new DOMDragEventCounter(right_frame()));
  state.expected_dom_event_data.set_expected_client_position("(55, 50)");
  state.expected_dom_event_data.set_expected_drop_effect("none");
  // (dragstart event handler in image_source.html is asking for "copy" only).
  state.expected_dom_event_data.set_expected_effect_allowed("copy");
  state.expected_dom_event_data.set_expected_mime_types(
      "text/html,text/plain,text/uri-list");
  state.expected_dom_event_data.set_expected_page_position("(55, 50)");

  // Start the drag in the left frame.
  DragStartWaiter drag_start_waiter(web_contents());
  drag_start_waiter.PostTaskWhenDragStarts(
      base::Bind(&DragAndDropBrowserTest::DragImageBetweenFrames_Step2,
                 base::Unretained(this), base::Unretained(&state)));
  state.dragstart_event_waiter.reset(
      new DOMDragEventWaiter("dragstart", left_frame()));
  EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());

  // The next step of the test (DragImageBetweenFrames_Step2) runs inside the
  // nested drag-and-drop message loop - the call below won't return until the
  // drag-and-drop has already ended.
  drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr);

  DragImageBetweenFrames_Step3(&state);
}

void DragAndDropBrowserTest::DragImageBetweenFrames_Step2(
    DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
  // Verify dragstart DOM event.
  {
    std::string dragstart_event;
    EXPECT_TRUE(state->dragstart_event_waiter->WaitForNextMatchingEvent(
        &dragstart_event));
    state->dragstart_event_waiter.reset();

    // Only a single "dragstart" should have fired in the left frame since the
    // start of the test.  We also allow any number of "dragover" events.
    EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                     "dragstart"));
    EXPECT_EQ(0, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                     {"dragleave", "dragenter", "drop", "dragend"}));

    // No events should have fired in the right frame yet.
    EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                     {"dragstart", "dragleave", "dragenter", "dragover", "drop",
                      "dragend"}));
  }

  // While dragging, move mouse within the left frame.
  // Without this extra mouse move we wouldn't get a dragleave event later on.
  ASSERT_TRUE(SimulateMouseMoveToLeftFrame());

  // While dragging, move mouse from the left into the right frame.
  // This should trigger dragleave and dragenter events.
  {
    DOMDragEventWaiter dragleave_event_waiter("dragleave", left_frame());
    DOMDragEventWaiter dragenter_event_waiter("dragenter", right_frame());
    state->left_frame_events_counter->Reset();
    state->right_frame_events_counter->Reset();
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    {  // Verify dragleave DOM event.
      std::string dragleave_event;

      state->expected_dom_event_data.set_expected_client_position("(355, 150)");
      state->expected_dom_event_data.set_expected_page_position("(355, 150)");

      EXPECT_TRUE(
          dragleave_event_waiter.WaitForNextMatchingEvent(&dragleave_event));
      EXPECT_THAT(dragleave_event, state->expected_dom_event_data.Matches());
    }

    {  // Verify dragenter DOM event.
      std::string dragenter_event;

      // Update expected event coordinates after SimulateMouseMoveToRightFrame
      // (these coordinates are relative to the right frame).
      state->expected_dom_event_data.set_expected_client_position("(155, 150)");
      state->expected_dom_event_data.set_expected_page_position("(155, 150)");

      EXPECT_TRUE(
          dragenter_event_waiter.WaitForNextMatchingEvent(&dragenter_event));
      EXPECT_THAT(dragenter_event, state->expected_dom_event_data.Matches());
    }

    // Note that ash (unlike aura/x11) will not fire dragover event in response
    // to the same mouse event that trigerred a dragenter.  Because of that, we
    // postpone dragover testing until the next test step below.  See
    // implementation of ash::DragDropController::DragUpdate for details.
  }

  // Move the mouse twice in the right frame.  The 1st move will ensure that
  // allowed operations communicated by the renderer will be stored in
  // WebContentsViewAura::current_drag_op_.  The 2nd move will ensure that this
  // gets be copied into DesktopDragDropClientAuraX11::negotiated_operation_.
  for (int i = 0; i < 2; i++) {
    DOMDragEventWaiter dragover_event_waiter("dragover", right_frame());
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    {  // Verify dragover DOM event.
      std::string dragover_event;
      EXPECT_TRUE(
          dragover_event_waiter.WaitForNextMatchingEvent(&dragover_event));
      EXPECT_THAT(dragover_event, state->expected_dom_event_data.Matches());
    }
  }

  // Only a single "dragleave" should have fired in the left frame since the
  // last checkpoint.  We also allow any number of "dragover" events.
  EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragleave"));
  EXPECT_EQ(0, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   {"dragstart", "dragenter", "drop", "dragend"}));

  // A single "dragenter" + at least one "dragover" event should have fired in
  // the right frame since the last checkpoint.
  EXPECT_EQ(1, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragenter"));
  EXPECT_LE(1, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragover"));
  EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   {"dragstart", "dragleave", "drop", "dragend"}));

  // Release the mouse button to end the drag.
  state->drop_event_waiter.reset(new DOMDragEventWaiter("drop", right_frame()));
  state->dragend_event_waiter.reset(
      new DOMDragEventWaiter("dragend", left_frame()));
  state->left_frame_events_counter->Reset();
  state->right_frame_events_counter->Reset();
  SimulateMouseUp();
  // The test will continue in DragImageBetweenFrames_Step3.
}

void DragAndDropBrowserTest::DragImageBetweenFrames_Step3(
    DragAndDropBrowserTest::DragImageBetweenFrames_TestState* state) {
  // Verify drop DOM event.
  {
    std::string drop_event;
    EXPECT_TRUE(
        state->drop_event_waiter->WaitForNextMatchingEvent(&drop_event));
    state->drop_event_waiter.reset();
    EXPECT_THAT(drop_event, state->expected_dom_event_data.Matches());
  }

  // Verify dragend DOM event.
  {
    // TODO(lukasza): Figure out why the drop event sees different values of
    // DataTransfer.dropEffect and DataTransfer.types properties.
    state->expected_dom_event_data.set_expected_drop_effect("copy");
    state->expected_dom_event_data.set_expected_mime_types("");

    // TODO: https://crbug.com/686136: dragEnd coordinates for non-OOPIF
    // scenarios are currently broken.
    state->expected_dom_event_data.set_expected_client_position(
        "<no expectation>");
    state->expected_dom_event_data.set_expected_page_position(
        "<no expectation>");

    std::string dragend_event;
    EXPECT_TRUE(
        state->dragend_event_waiter->WaitForNextMatchingEvent(&dragend_event));
    state->dragend_event_waiter.reset();
    EXPECT_THAT(dragend_event, state->expected_dom_event_data.Matches());
  }

  // Only a single "dragend" should have fired in the left frame since the last
  // checkpoint.
  EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragend"));
  EXPECT_EQ(0,
            state->left_frame_events_counter->GetNumberOfReceivedEvents(
                {"dragstart", "dragleave", "dragenter", "dragover", "drop"}));

  // A single "drop" + possibly some "dragover" events should have fired in the
  // right frame since the last checkpoint.
  EXPECT_EQ(
      1, state->right_frame_events_counter->GetNumberOfReceivedEvents("drop"));
  EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   {"dragstart", "dragleave", "dragenter", "dragend"}));
}

#if defined(OS_WIN)
// There is no known way to execute test-controlled tasks during
// a drag-and-drop loop run by Windows OS.
#define MAYBE_DragImageFromDisappearingFrame \
  DISABLED_DragImageFromDisappearingFrame
#elif defined(OS_CHROMEOS)
// Flakiness on CrOS tracked by https://crbug.com/835572.
#define MAYBE_DragImageFromDisappearingFrame \
  DISABLED_DragImageFromDisappearingFrame
#else
#define MAYBE_DragImageFromDisappearingFrame DragImageFromDisappearingFrame
#endif

// Data that needs to be shared across multiple test steps below
// (i.e. across DragImageFromDisappearingFrame_Step2 and
// DragImageFromDisappearingFrame_Step3).
struct DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState {
  DOMDragEventVerifier expected_dom_event_data;
  std::unique_ptr<DOMDragEventWaiter> drop_event_waiter;
};

// Scenario: drag an image from the left into the right frame and delete the
// left frame during the drag.  This is a regression test for
// https://crbug.com/670123.
// Test coverage: dragenter, dragover, drop DOM events.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest,
                       MAYBE_DragImageFromDisappearingFrame) {
  // Load the test page.
  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateLeftFrame(frame_site, "image_source.html"));
  ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));

  // Setup test expectations.
  DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState state;
  state.expected_dom_event_data.set_expected_drop_effect("none");
  // (dragstart event handler in image_source.html is asking for "copy" only).
  state.expected_dom_event_data.set_expected_effect_allowed("copy");
  state.expected_dom_event_data.set_expected_mime_types(
      "text/html,text/plain,text/uri-list");
  state.expected_dom_event_data.set_expected_client_position("(155, 150)");
  state.expected_dom_event_data.set_expected_page_position("(155, 150)");

  // Start the drag in the left frame.
  DragStartWaiter drag_start_waiter(web_contents());
  drag_start_waiter.PostTaskWhenDragStarts(
      base::Bind(&DragAndDropBrowserTest::DragImageFromDisappearingFrame_Step2,
                 base::Unretained(this), base::Unretained(&state)));
  EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());

  // The next step of the test (DragImageFromDisappearingFrame_Step2) runs
  // inside the nested drag-and-drop message loop - the call below won't return
  // until the drag-and-drop has already ended.
  drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr);

  DragImageFromDisappearingFrame_Step3(&state);
}

void DragAndDropBrowserTest::DragImageFromDisappearingFrame_Step2(
    DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState* state) {
  // Delete the left frame in an attempt to repro https://crbug.com/670123.
  content::RenderFrameDeletedObserver frame_deleted_observer(left_frame());
  ASSERT_TRUE(ExecuteScript(web_contents()->GetMainFrame(),
                            "frame = document.getElementById('left');\n"
                            "frame.parentNode.removeChild(frame);\n"));
  frame_deleted_observer.WaitUntilDeleted();

  // While dragging, move mouse from the left into the right frame.
  // This should trigger dragleave and dragenter events.
  {
    DOMDragEventWaiter dragenter_event_waiter("dragenter", right_frame());
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    {  // Verify dragenter DOM event.
      std::string dragenter_event;
      EXPECT_TRUE(
          dragenter_event_waiter.WaitForNextMatchingEvent(&dragenter_event));
      EXPECT_THAT(dragenter_event, state->expected_dom_event_data.Matches());
    }

    // Note that ash (unlike aura/x11) will not fire dragover event in response
    // to the same mouse event that trigerred a dragenter.  Because of that, we
    // postpone dragover testing until the next test step below.  See
    // implementation of ash::DragDropController::DragUpdate for details.
  }

  // Move the mouse twice in the right frame.  The 1st move will ensure that
  // allowed operations communicated by the renderer will be stored in
  // WebContentsViewAura::current_drag_op_.  The 2nd move will ensure that this
  // gets be copied into DesktopDragDropClientAuraX11::negotiated_operation_.
  for (int i = 0; i < 2; i++) {
    DOMDragEventWaiter dragover_event_waiter("dragover", right_frame());
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    {  // Verify dragover DOM event.
      std::string dragover_event;
      EXPECT_TRUE(
          dragover_event_waiter.WaitForNextMatchingEvent(&dragover_event));
      EXPECT_THAT(dragover_event, state->expected_dom_event_data.Matches());
    }
  }

  // Release the mouse button to end the drag.
  state->drop_event_waiter.reset(new DOMDragEventWaiter("drop", right_frame()));
  SimulateMouseUp();
  // The test will continue in DragImageFromDisappearingFrame_Step3.
}

void DragAndDropBrowserTest::DragImageFromDisappearingFrame_Step3(
    DragAndDropBrowserTest::DragImageFromDisappearingFrame_TestState* state) {
  // Verify drop DOM event.
  {
    std::string drop_event;
    EXPECT_TRUE(
        state->drop_event_waiter->WaitForNextMatchingEvent(&drop_event));
    state->drop_event_waiter.reset();
    EXPECT_THAT(drop_event, state->expected_dom_event_data.Matches());
  }
}

// There is no known way to execute test-controlled tasks during
// a drag-and-drop loop run by Windows OS.
#if defined(OS_WIN)
#define MAYBE_CrossSiteDrag DISABLED_CrossSiteDrag
#elif defined(OS_CHROMEOS)
// Flaky: https://crbug.com/835774
#define MAYBE_CrossSiteDrag DISABLED_CrossSiteDrag
#else
#define MAYBE_CrossSiteDrag CrossSiteDrag
#endif

// Data that needs to be shared across multiple test steps below
// (i.e. across CrossSiteDrag_Step2 and CrossSiteDrag_Step3).
struct DragAndDropBrowserTest::CrossSiteDrag_TestState {
  std::unique_ptr<DOMDragEventWaiter> dragend_event_waiter;
  std::unique_ptr<DOMDragEventCounter> left_frame_events_counter;
  std::unique_ptr<DOMDragEventCounter> right_frame_events_counter;
};

// Scenario: drag an image from the left into the right frame when the
// left-vs-right frames are cross-site.  This is a regression test for
// https://crbug.com/59081.
//
// Test coverage: absence of dragenter, dragover, drop DOM events
// + presence of dragstart, dragleave and dragend.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, MAYBE_CrossSiteDrag) {
  std::string left_frame_site = "c.com";  // Always cross-site VS main frame.
  std::string right_frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateLeftFrame(left_frame_site, "image_source.html"));
  ASSERT_TRUE(NavigateRightFrame(right_frame_site, "drop_target.html"));

  // Setup test expectations.
  DragAndDropBrowserTest::CrossSiteDrag_TestState state;
  state.left_frame_events_counter.reset(new DOMDragEventCounter(left_frame()));
  state.right_frame_events_counter.reset(
      new DOMDragEventCounter(right_frame()));

  // Start the drag in the left frame.
  DragStartWaiter drag_start_waiter(web_contents());
  drag_start_waiter.PostTaskWhenDragStarts(
      base::Bind(&DragAndDropBrowserTest::CrossSiteDrag_Step2,
                 base::Unretained(this), base::Unretained(&state)));
  EXPECT_TRUE(SimulateMouseDownAndDragStartInLeftFrame());

  // The next step of the test (CrossSiteDrag_Step2) runs inside the
  // nested drag-and-drop message loop - the call below won't return until the
  // drag-and-drop has already ended.
  drag_start_waiter.WaitUntilDragStart(nullptr, nullptr, nullptr, nullptr);

  CrossSiteDrag_Step3(&state);
}

void DragAndDropBrowserTest::CrossSiteDrag_Step2(
    DragAndDropBrowserTest::CrossSiteDrag_TestState* state) {
  // While "dragleave" and "drop" events are not expected in this test, we
  // simulate extra mouse operations for consistency with
  // DragImageBetweenFrames_Step2.
  ASSERT_TRUE(SimulateMouseMoveToLeftFrame());
  for (int i = 0; i < 3; i++) {
    content::DOMMessageQueue dom_message_queue(web_contents());
    ASSERT_TRUE(SimulateMouseMoveToRightFrame());

    // No events are expected from the right frame, so we can't wait for a
    // dragover event here.  Still - we do want to wait until the right frame
    // has had a chance to process any previous browser IPCs, so that in case
    // there *is* a bug and a dragover event *does* happen, we won't terminate
    // the test before the event has had a chance to be reported back to the
    // browser.
    std::string expected_response = base::StringPrintf("\"i%d\"", i);
    right_frame()->ExecuteJavaScriptWithUserGestureForTests(
        base::UTF8ToUTF16(base::StringPrintf(
            "domAutomationController.send(%s);", expected_response.c_str())));

    // Wait until our response comes back (it might be mixed with responses
    // carrying events that are sent by event_monitoring.js).
    std::string actual_response;
    do {
      ASSERT_TRUE(dom_message_queue.WaitForMessage(&actual_response));
    } while (actual_response != expected_response);
  }

  // Release the mouse button to end the drag.
  state->dragend_event_waiter.reset(
      new DOMDragEventWaiter("dragend", left_frame()));
  SimulateMouseUp();
  // The test will continue in DragImageBetweenFrames_Step3.
}

void DragAndDropBrowserTest::CrossSiteDrag_Step3(
    DragAndDropBrowserTest::CrossSiteDrag_TestState* state) {
  EXPECT_TRUE(state->dragend_event_waiter->WaitForNextMatchingEvent(nullptr));

  // Since the start of the test the left frame should have seen a single
  // "dragstart",
  // and a "dragend" event (and possibly a "dragleave" and some "dragover"
  // events).
  EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragstart"));
  EXPECT_EQ(1, state->left_frame_events_counter->GetNumberOfReceivedEvents(
                   "dragend"));
  EXPECT_EQ(
      0, state->left_frame_events_counter->GetNumberOfReceivedEvents("drop"));

  // No events should have fired in the right frame, because it is cross-site
  // from the source of the drag.  This is the essence of this test.
  EXPECT_EQ(0, state->right_frame_events_counter->GetNumberOfReceivedEvents(
                   {"dragstart", "dragleave", "dragenter", "dragover", "drop",
                    "dragend"}));
}

// Test that screenX/screenY for drag updates are in screen coordinates.
// See https://crbug.com/600402 where we mistook the root window coordinate
// space for the screen coordinate space.
IN_PROC_BROWSER_TEST_P(DragAndDropBrowserTest, DragUpdateScreenCoordinates) {
  // Reposition the window so that the root window coordinate space and the
  // screen coordinate space are clearly distinct. Otherwise this test would
  // be inconclusive.
  // In addition to offsetting the window, use a small window size to avoid
  // rejection of the new bounds by the system.
  browser()->window()->SetBounds(gfx::Rect(200, 100, 700, 500));
  do {
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
  } while (browser()->window()->GetBounds().origin() != gfx::Point(200, 100));

  std::string frame_site = use_cross_site_subframe() ? "b.com" : "a.com";
  ASSERT_TRUE(NavigateToTestPage("a.com"));
  ASSERT_TRUE(NavigateRightFrame(frame_site, "drop_target.html"));

  const gfx::Point screen_position = GetMiddleOfRightFrameInScreenCoords();

  DOMDragEventVerifier expected_dom_event_data;
  expected_dom_event_data.set_expected_client_position("(155, 150)");
  expected_dom_event_data.set_expected_screen_position(
      base::StringPrintf("(%d, %d)", screen_position.x(), screen_position.y()));

  DOMDragEventWaiter dragover_waiter("dragover", right_frame());
  ASSERT_TRUE(SimulateDragEnterToRightFrame("Dragged test text"));

  std::string dragover_event;
  ASSERT_TRUE(dragover_waiter.WaitForNextMatchingEvent(&dragover_event));
  EXPECT_THAT(dragover_event, expected_dom_event_data.Matches());
}

// TODO(paulmeyer): Should test the case of navigation happening in the middle
// of a drag operation, and cross-site drags should be allowed across a
// navigation.

INSTANTIATE_TEST_SUITE_P(SameSiteSubframe,
                         DragAndDropBrowserTest,
                         ::testing::Values(false));

INSTANTIATE_TEST_SUITE_P(CrossSiteSubframe,
                         DragAndDropBrowserTest,
                         ::testing::Values(true));

}  // namespace chrome
