Add test_runner hook to dump drag image.

This is a second attempt at:
https://codereview.chromium.org/904833004/
which caused flakiness in pixel tests and was reverted here:
https://codereview.chromium.org/919273002/

This CL merges the fix from:
https://codereview.chromium.org/918313003/

It also handles the case where dumpDragImage is called but no drag occurs
by dumping a 1x1 empty transparent image.

This is used by:
https://codereview.chromium.org/886323005/

BUG=451759, 458077

Review URL: https://codereview.chromium.org/916893003

Cr-Commit-Position: refs/heads/master@{#316194}
diff --git a/content/shell/renderer/test_runner/test_runner.cc b/content/shell/renderer/test_runner/test_runner.cc
index 7bf164b..2b79535 100644
--- a/content/shell/renderer/test_runner/test_runner.cc
+++ b/content/shell/renderer/test_runner/test_runner.cc
@@ -255,6 +255,7 @@
   void DumpResourceRequestPriorities();
   void SetUseMockTheme(bool use);
   void WaitUntilExternalURLLoad();
+  void DumpDragImage();
   void ShowWebInspector(gin::Arguments* args);
   void CloseWebInspector();
   bool IsChooserShown();
@@ -493,6 +494,7 @@
       .SetMethod("setUseMockTheme", &TestRunnerBindings::SetUseMockTheme)
       .SetMethod("waitUntilExternalURLLoad",
                  &TestRunnerBindings::WaitUntilExternalURLLoad)
+      .SetMethod("dumpDragImage", &TestRunnerBindings::DumpDragImage)
       .SetMethod("showWebInspector", &TestRunnerBindings::ShowWebInspector)
       .SetMethod("closeWebInspector", &TestRunnerBindings::CloseWebInspector)
       .SetMethod("isChooserShown", &TestRunnerBindings::IsChooserShown)
@@ -1225,6 +1227,11 @@
     runner_->WaitUntilExternalURLLoad();
 }
 
+void TestRunnerBindings::DumpDragImage() {
+  if (runner_)
+    runner_->DumpDragImage();
+}
+
 void TestRunnerBindings::ShowWebInspector(gin::Arguments* args) {
   if (runner_) {
     std::string settings;
@@ -1659,6 +1666,7 @@
   dump_spell_check_callbacks_ = false;
   dump_back_forward_list_ = false;
   dump_selection_rect_ = false;
+  dump_drag_image_ = false;
   test_repaint_ = false;
   sweep_horizontally_ = false;
   is_printing_ = false;
@@ -1929,6 +1937,10 @@
   tooltip_text_ = text.utf8();
 }
 
+bool TestRunner::shouldDumpDragImage() {
+  return dump_drag_image_;
+}
+
 bool TestRunner::midiAccessorResult() {
   return midi_accessor_result_;
 }
@@ -2725,6 +2737,11 @@
   wait_until_external_url_load_ = true;
 }
 
+void TestRunner::DumpDragImage() {
+  DumpAsTextWithPixelResults();
+  dump_drag_image_ = true;
+}
+
 void TestRunner::CloseWebInspector() {
   delegate_->CloseDevTools();
 }
diff --git a/content/shell/renderer/test_runner/test_runner.h b/content/shell/renderer/test_runner/test_runner.h
index ffb6bf0a..0a6e704b 100644
--- a/content/shell/renderer/test_runner/test_runner.h
+++ b/content/shell/renderer/test_runner/test_runner.h
@@ -119,6 +119,7 @@
   void RequestPointerUnlock();
   bool isPointerLocked();
   void setToolTipText(const blink::WebString&);
+  bool shouldDumpDragImage();
 
   bool midiAccessorResult();
 
@@ -469,6 +470,12 @@
   // WebFrameClient receives a loadURLExternally() call.
   void WaitUntilExternalURLLoad();
 
+  // This function sets a flag which tells the WebTestProxy to dump the drag
+  // image when the next drag-and-drop is initiated. It is equivalent to
+  // DumpAsTextWithPixelResults but the pixel results will be the drag image
+  // instead of a snapshot of the page.
+  void DumpDragImage();
+
   ///////////////////////////////////////////////////////////////////////////
   // Methods interacting with the WebTestProxy
 
@@ -739,6 +746,9 @@
   // taking possible transforms of the selection rect into account.
   bool dump_selection_rect_;
 
+  // If true, the test_shell will dump the drag image as pixel results.
+  bool dump_drag_image_;
+
   // If true, pixel dump will be produced as a series of 1px-tall, view-wide
   // individual paints over the height of the view.
   bool test_repaint_;
diff --git a/content/shell/renderer/test_runner/web_test_proxy.cc b/content/shell/renderer/test_runner/web_test_proxy.cc
index da62fc0..37aa1f7 100644
--- a/content/shell/renderer/test_runner/web_test_proxy.cc
+++ b/content/shell/renderer/test_runner/web_test_proxy.cc
@@ -375,6 +375,7 @@
 }
 
 void WebTestProxyBase::Reset() {
+  drag_image_.reset();
   animate_scheduled_ = false;
   resource_identifier_map_.clear();
   log_console_output_ = true;
@@ -565,6 +566,24 @@
   TRACE_EVENT0("shell", "WebTestProxyBase::CapturePixelsAsync");
   DCHECK(!callback.is_null());
 
+  if (test_interfaces_->GetTestRunner()->shouldDumpDragImage()) {
+    if (drag_image_.isNull()) {
+      // This means the test called dumpDragImage but did not initiate a drag.
+      // Return a blank image so that the test fails.
+      SkBitmap bitmap;
+      bitmap.allocN32Pixels(1, 1);
+      {
+        SkAutoLockPixels lock(bitmap);
+        bitmap.eraseColor(0);
+      }
+      callback.Run(bitmap);
+      return;
+    }
+
+    callback.Run(drag_image_.getSkBitmap());
+    return;
+  }
+
   if (test_interfaces_->GetTestRunner()->isPrinting()) {
     base::MessageLoopProxy::current()->PostTask(
         FROM_HERE,
@@ -806,6 +825,10 @@
                                      blink::WebDragOperationsMask mask,
                                      const blink::WebImage& image,
                                      const blink::WebPoint& point) {
+  if (test_interfaces_->GetTestRunner()->shouldDumpDragImage()) {
+    if (drag_image_.isNull())
+      drag_image_ = image;
+  }
   // When running a test, we need to fake a drag drop operation otherwise
   // Windows waits for real mouse events to know when the drag is over.
   test_interfaces_->GetEventSender()->DoDragDrop(data, mask);
diff --git a/content/shell/renderer/test_runner/web_test_proxy.h b/content/shell/renderer/test_runner/web_test_proxy.h
index e06d572..88dd814 100644
--- a/content/shell/renderer/test_runner/web_test_proxy.h
+++ b/content/shell/renderer/test_runner/web_test_proxy.h
@@ -13,6 +13,7 @@
 #include "base/callback.h"
 #include "base/memory/scoped_ptr.h"
 #include "content/shell/renderer/test_runner/web_task.h"
+#include "third_party/WebKit/public/platform/WebImage.h"
 #include "third_party/WebKit/public/platform/WebRect.h"
 #include "third_party/WebKit/public/platform/WebScreenInfo.h"
 #include "third_party/WebKit/public/platform/WebURLError.h"
@@ -44,7 +45,6 @@
 class WebDragData;
 class WebFileChooserCompletion;
 class WebFrame;
-class WebImage;
 class WebLocalFrame;
 class WebMIDIAccessor;
 class WebMIDIAccessorClient;
@@ -254,6 +254,8 @@
 
   WebTaskList task_list_;
 
+  blink::WebImage drag_image_;
+
   scoped_ptr<SpellCheckClient> spellcheck_;
   scoped_ptr<MockWebUserMediaClient> user_media_client_;