V8ValueConverterImpl: Use V8 to copy from array buffers.

It is no longer necessary to route through Blink and externalize them.
This has the side effect of not requiring all of the Blink machinery to be
set up in order to convert binary values from V8.

Review-Url: https://codereview.chromium.org/2685743002
Cr-Commit-Position: refs/heads/master@{#448997}
diff --git a/content/child/v8_value_converter_impl.cc b/content/child/v8_value_converter_impl.cc
index 5dcf636..dd36788 100644
--- a/content/child/v8_value_converter_impl.cc
+++ b/content/child/v8_value_converter_impl.cc
@@ -17,9 +17,6 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "base/values.h"
-#include "third_party/WebKit/public/web/WebArrayBuffer.h"
-#include "third_party/WebKit/public/web/WebArrayBufferConverter.h"
-#include "third_party/WebKit/public/web/WebArrayBufferView.h"
 #include "v8/include/v8.h"
 
 namespace content {
@@ -339,11 +336,11 @@
     v8::Isolate* isolate,
     v8::Local<v8::Object> creation_context,
     const base::BinaryValue* value) const {
-  blink::WebArrayBuffer buffer =
-      blink::WebArrayBuffer::create(value->GetSize(), 1);
-  memcpy(buffer.data(), value->GetBuffer(), value->GetSize());
-  return blink::WebArrayBufferConverter::toV8Value(
-      &buffer, creation_context, isolate);
+  DCHECK(creation_context->CreationContext() == isolate->GetCurrentContext());
+  v8::Local<v8::ArrayBuffer> buffer =
+      v8::ArrayBuffer::New(isolate, value->GetSize());
+  memcpy(buffer->GetContents().Data(), value->GetBuffer(), value->GetSize());
+  return buffer;
 }
 
 std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8ValueImpl(
@@ -497,27 +494,20 @@
       return out;
   }
 
-  char* data = NULL;
-  size_t length = 0;
-
-  std::unique_ptr<blink::WebArrayBuffer> array_buffer(
-      blink::WebArrayBufferConverter::createFromV8Value(val, isolate));
-  std::unique_ptr<blink::WebArrayBufferView> view;
-  if (array_buffer) {
-    data = reinterpret_cast<char*>(array_buffer->data());
-    length = array_buffer->byteLength();
+  if (val->IsArrayBuffer()) {
+    auto contents = val.As<v8::ArrayBuffer>()->GetContents();
+    return base::BinaryValue::CreateWithCopiedBuffer(
+        static_cast<const char*>(contents.Data()), contents.ByteLength());
+  } else if (val->IsArrayBufferView()) {
+    v8::Local<v8::ArrayBufferView> view = val.As<v8::ArrayBufferView>();
+    size_t byte_length = view->ByteLength();
+    auto buffer = base::MakeUnique<char[]>(byte_length);
+    view->CopyContents(buffer.get(), byte_length);
+    return base::MakeUnique<base::BinaryValue>(std::move(buffer), byte_length);
   } else {
-    view.reset(blink::WebArrayBufferView::createFromV8Value(val));
-    if (view) {
-      data = reinterpret_cast<char*>(view->baseAddress()) + view->byteOffset();
-      length = view->byteLength();
-    }
-  }
-
-  if (data)
-    return base::BinaryValue::CreateWithCopiedBuffer(data, length);
-  else
+    NOTREACHED() << "Only ArrayBuffer and ArrayBufferView should get here.";
     return nullptr;
+  }
 }
 
 std::unique_ptr<base::Value> V8ValueConverterImpl::FromV8Object(
diff --git a/content/child/v8_value_converter_impl_unittest.cc b/content/child/v8_value_converter_impl_unittest.cc
index a403751..84d03fc 100644
--- a/content/child/v8_value_converter_impl_unittest.cc
+++ b/content/child/v8_value_converter_impl_unittest.cc
@@ -1108,8 +1108,29 @@
   EXPECT_TRUE(
       base::Value::Equals(reference_array_value.get(), array_value.get()));
 
-  // Not testing ArrayBuffers as V8ValueConverter uses blink helpers and
-  // this requires having blink to be initialized.
+  const char kExampleData[] = {1, 2, 3, 4, 5};
+  v8::Local<v8::ArrayBuffer> array_buffer(
+      v8::ArrayBuffer::New(isolate_, sizeof(kExampleData)));
+  memcpy(array_buffer->GetContents().Data(), kExampleData,
+         sizeof(kExampleData));
+  std::unique_ptr<base::Value> binary_value(
+      converter.FromV8Value(array_buffer, context));
+  ASSERT_TRUE(binary_value);
+  std::unique_ptr<base::Value> reference_binary_value(
+      base::BinaryValue::CreateWithCopiedBuffer(kExampleData,
+                                                sizeof(kExampleData)));
+  EXPECT_TRUE(
+      base::Value::Equals(reference_binary_value.get(), binary_value.get()));
+
+  v8::Local<v8::ArrayBufferView> array_buffer_view(
+      v8::Uint8Array::New(array_buffer, 1, 3));
+  std::unique_ptr<base::Value> binary_view_value(
+      converter.FromV8Value(array_buffer_view, context));
+  ASSERT_TRUE(binary_view_value);
+  std::unique_ptr<base::Value> reference_binary_view_value(
+      base::BinaryValue::CreateWithCopiedBuffer(&kExampleData[1], 3));
+  EXPECT_TRUE(base::Value::Equals(reference_binary_view_value.get(),
+                                  binary_view_value.get()));
 
   v8::Local<v8::Number> number(v8::Number::New(isolate_, 0.0));
   std::unique_ptr<base::Value> number_value(