Commit 9cd36bfb authored by morrita@chromium.org's avatar morrita@chromium.org

Add IPC benchmarking API to window behind --expose-ipc-echo

This add an window.ipcEcho API that sends do-nothing IPC 
message to measure RTT. The API is behind a flag, 
and will be used to build IPC benchmark using JavaScript.

TEST=none (Will add blink-side LayoutTest once this is landed)
BUG=402185
R=darin@chromium.org, jam@chromim.org, jochen@chromium.org

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=290063

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

Cr-Commit-Position: refs/heads/master@{#290715}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290715 0039d316-1c4b-4281-b951-d872f2087c98
parent 39a85b63
...@@ -88,6 +88,8 @@ ...@@ -88,6 +88,8 @@
'shell/app/webkit_test_platform_support_linux.cc', 'shell/app/webkit_test_platform_support_linux.cc',
'shell/app/webkit_test_platform_support_mac.mm', 'shell/app/webkit_test_platform_support_mac.mm',
'shell/app/webkit_test_platform_support_win.cc', 'shell/app/webkit_test_platform_support_win.cc',
'shell/browser/ipc_echo_message_filter.cc',
'shell/browser/ipc_echo_message_filter.h',
'shell/browser/notify_done_forwarder.cc', 'shell/browser/notify_done_forwarder.cc',
'shell/browser/notify_done_forwarder.h', 'shell/browser/notify_done_forwarder.h',
'shell/browser/shell_android.cc', 'shell/browser/shell_android.cc',
...@@ -167,6 +169,8 @@ ...@@ -167,6 +169,8 @@
'shell/geolocation/shell_access_token_store.h', 'shell/geolocation/shell_access_token_store.h',
'shell/renderer/gc_controller.cc', 'shell/renderer/gc_controller.cc',
'shell/renderer/gc_controller.h', 'shell/renderer/gc_controller.h',
'shell/renderer/ipc_echo.cc',
'shell/renderer/ipc_echo.h',
'shell/renderer/leak_detector.cc', 'shell/renderer/leak_detector.cc',
'shell/renderer/leak_detector.h', 'shell/renderer/leak_detector.h',
'shell/renderer/shell_content_renderer_client.cc', 'shell/renderer/shell_content_renderer_client.cc',
......
...@@ -38,6 +38,8 @@ static_library("content_shell_lib") { ...@@ -38,6 +38,8 @@ static_library("content_shell_lib") {
"app/webkit_test_platform_support_linux.cc", "app/webkit_test_platform_support_linux.cc",
"app/webkit_test_platform_support_mac.mm", "app/webkit_test_platform_support_mac.mm",
"app/webkit_test_platform_support_win.cc", "app/webkit_test_platform_support_win.cc",
"browser/ipc_echo_message_filter.cc",
"browser/ipc_echo_message_filter.h",
"browser/notify_done_forwarder.cc", "browser/notify_done_forwarder.cc",
"browser/notify_done_forwarder.h", "browser/notify_done_forwarder.h",
"browser/shell_android.cc", "browser/shell_android.cc",
...@@ -115,6 +117,8 @@ static_library("content_shell_lib") { ...@@ -115,6 +117,8 @@ static_library("content_shell_lib") {
"geolocation/shell_access_token_store.h", "geolocation/shell_access_token_store.h",
"renderer/gc_controller.cc", "renderer/gc_controller.cc",
"renderer/gc_controller.h", "renderer/gc_controller.h",
"renderer/ipc_echo.cc",
"renderer/ipc_echo.h",
"renderer/leak_detector.cc", "renderer/leak_detector.cc",
"renderer/leak_detector.h", "renderer/leak_detector.h",
"renderer/shell_content_renderer_client.cc", "renderer/shell_content_renderer_client.cc",
......
// Copyright 2014 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 "content/shell/browser/ipc_echo_message_filter.h"
#include "content/shell/common/shell_messages.h"
namespace content {
IPCEchoMessageFilter::IPCEchoMessageFilter()
: BrowserMessageFilter(ShellMsgStart) {
}
IPCEchoMessageFilter::~IPCEchoMessageFilter() {
}
bool IPCEchoMessageFilter::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(IPCEchoMessageFilter, message)
IPC_MESSAGE_HANDLER(ShellViewHostMsg_EchoPing, OnEchoPing)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void IPCEchoMessageFilter::OnEchoPing(int routing_id, int id,
const std::string& body) {
Send(new ShellViewMsg_EchoPong(routing_id, id, body));
}
} // namespace content
// Copyright 2014 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.
#ifndef CONTENT_SHELL_BROWSER_IPC_ECHO_MESSAGE_FILTER_H_
#define CONTENT_SHELL_BROWSER_IPC_ECHO_MESSAGE_FILTER_H_
#include <string>
#include "content/public/browser/browser_message_filter.h"
namespace content {
class IPCEchoMessageFilter : public BrowserMessageFilter {
public:
IPCEchoMessageFilter();
private:
virtual ~IPCEchoMessageFilter();
// BrowserMessageFilter implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
void OnEchoPing(int routing_id, int id, const std::string& body);
DISALLOW_COPY_AND_ASSIGN(IPCEchoMessageFilter);
};
} // namespace content
#endif // CONTENT_SHELL_BROWSER_IPC_ECHO_MESSAGE_FILTER_H_
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h" #include "content/public/common/url_constants.h"
#include "content/public/common/web_preferences.h" #include "content/public/common/web_preferences.h"
#include "content/shell/browser/ipc_echo_message_filter.h"
#include "content/shell/browser/shell.h" #include "content/shell/browser/shell.h"
#include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_browser_context.h"
#include "content/shell/browser/shell_browser_main_parts.h" #include "content/shell/browser/shell_browser_main_parts.h"
...@@ -170,6 +171,8 @@ BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts( ...@@ -170,6 +171,8 @@ BrowserMainParts* ShellContentBrowserClient::CreateBrowserMainParts(
void ShellContentBrowserClient::RenderProcessWillLaunch( void ShellContentBrowserClient::RenderProcessWillLaunch(
RenderProcessHost* host) { RenderProcessHost* host) {
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kExposeIpcEcho))
host->AddFilter(new IPCEchoMessageFilter());
if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree))
return; return;
host->AddFilter(new ShellMessageFilter( host->AddFilter(new ShellMessageFilter(
...@@ -240,6 +243,9 @@ void ShellContentBrowserClient::AppendExtraCommandLineSwitches( ...@@ -240,6 +243,9 @@ void ShellContentBrowserClient::AppendExtraCommandLineSwitches(
if (CommandLine::ForCurrentProcess()->HasSwitch( if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kExposeInternalsForTesting)) switches::kExposeInternalsForTesting))
command_line->AppendSwitch(switches::kExposeInternalsForTesting); command_line->AppendSwitch(switches::kExposeInternalsForTesting);
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kExposeIpcEcho))
command_line->AppendSwitch(switches::kExposeIpcEcho);
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStableReleaseMode)) if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kStableReleaseMode))
command_line->AppendSwitch(switches::kStableReleaseMode); command_line->AppendSwitch(switches::kStableReleaseMode);
if (CommandLine::ForCurrentProcess()->HasSwitch( if (CommandLine::ForCurrentProcess()->HasSwitch(
......
...@@ -113,6 +113,14 @@ IPC_MESSAGE_ROUTED1(ShellViewHostMsg_SetDeviceScaleFactor, ...@@ -113,6 +113,14 @@ IPC_MESSAGE_ROUTED1(ShellViewHostMsg_SetDeviceScaleFactor,
IPC_MESSAGE_ROUTED0(ShellViewHostMsg_CaptureSessionHistory) IPC_MESSAGE_ROUTED0(ShellViewHostMsg_CaptureSessionHistory)
IPC_MESSAGE_ROUTED0(ShellViewHostMsg_CloseRemainingWindows) IPC_MESSAGE_ROUTED0(ShellViewHostMsg_CloseRemainingWindows)
IPC_MESSAGE_CONTROL3(ShellViewHostMsg_EchoPing,
int /* routing_id */,
int /* id */,
std::string /* body */)
IPC_MESSAGE_ROUTED2(ShellViewMsg_EchoPong,
int /* id */,
std::string /* body */)
IPC_STRUCT_TRAITS_BEGIN(content::LeakDetectionResult) IPC_STRUCT_TRAITS_BEGIN(content::LeakDetectionResult)
IPC_STRUCT_TRAITS_MEMBER(leaked) IPC_STRUCT_TRAITS_MEMBER(leaked)
IPC_STRUCT_TRAITS_MEMBER(detail) IPC_STRUCT_TRAITS_MEMBER(detail)
......
...@@ -28,6 +28,9 @@ const char kCrashOnFailure[] = "crash-on-failure"; ...@@ -28,6 +28,9 @@ const char kCrashOnFailure[] = "crash-on-failure";
// Request pages to be dumped as text once they finished loading. // Request pages to be dumped as text once they finished loading.
const char kDumpRenderTree[] = "dump-render-tree"; const char kDumpRenderTree[] = "dump-render-tree";
// Expose window.ipcTester object for testing
const char kExposeIpcEcho[] = "expose-ipc-echo";
// Enable accelerated 2D canvas. // Enable accelerated 2D canvas.
const char kEnableAccelerated2DCanvas[] = "enable-accelerated-2d-canvas"; const char kEnableAccelerated2DCanvas[] = "enable-accelerated-2d-canvas";
......
...@@ -16,6 +16,7 @@ extern const char kContentShellDataPath[]; ...@@ -16,6 +16,7 @@ extern const char kContentShellDataPath[];
extern const char kCrashDumpsDir[]; extern const char kCrashDumpsDir[];
extern const char kCrashOnFailure[]; extern const char kCrashOnFailure[];
extern const char kDumpRenderTree[]; extern const char kDumpRenderTree[];
extern const char kExposeIpcEcho[];
extern const char kEnableAccelerated2DCanvas[]; extern const char kEnableAccelerated2DCanvas[];
extern const char kEnableFontAntialiasing[]; extern const char kEnableFontAntialiasing[];
extern const char kEnableLeakDetection[]; extern const char kEnableLeakDetection[];
......
// Copyright 2014 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.
#ifndef CONTENT_SHELL_BINDING_HELPERS_H_
#define CONTENT_SHELL_BINDING_HELPERS_H_
#include <string>
#include <vector>
#include "base/memory/scoped_ptr.h"
#include "gin/handle.h"
#include "gin/wrappable.h"
#include "third_party/WebKit/public/web/WebFrame.h"
#include "third_party/WebKit/public/web/WebKit.h"
namespace content {
template<class WrappedClass>
void InstallAsWindowProperties(WrappedClass* wrapped,
blink::WebFrame* frame,
const std::vector<std::string>& names) {
v8::Isolate* isolate = blink::mainThreadIsolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::Context> context = frame->mainWorldScriptContext();
if (context.IsEmpty())
return;
v8::Context::Scope context_scope(context);
gin::Handle<WrappedClass> bindings = gin::CreateHandle(isolate, wrapped);
if (bindings.IsEmpty())
return;
v8::Handle<v8::Object> global = context->Global();
v8::Handle<v8::Value> v8_bindings = bindings.ToV8();
for (size_t i = 0; i < names.size(); ++i)
global->Set(gin::StringToV8(isolate, names[i].c_str()), v8_bindings);
}
} // namespace content
#endif // CONTENT_SHELL_BINDING_HELPERS_DISPATCHER_H_
// Copyright 2014 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 "content/shell/renderer/ipc_echo.h"
#include "base/logging.h"
#include "content/shell/common/shell_messages.h"
#include "content/shell/renderer/binding_helpers.h"
#include "gin/object_template_builder.h"
#include "gin/wrappable.h"
#include "ipc/ipc_sender.h"
#include "third_party/WebKit/public/web/WebDOMCustomEvent.h"
#include "third_party/WebKit/public/web/WebDOMEvent.h"
#include "third_party/WebKit/public/web/WebSerializedScriptValue.h"
namespace content {
class IPCEchoBindings : public gin::Wrappable<IPCEchoBindings> {
public:
static gin::WrapperInfo kWrapperInfo;
static void Install(base::WeakPtr<IPCEcho> echo, blink::WebFrame* frame);
explicit IPCEchoBindings(base::WeakPtr<IPCEcho>);
void RequestEcho(int id, int size);
int GetLastEchoId() const;
int GetLastEchoSize() const;
private:
virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate*) OVERRIDE;
base::WeakPtr<IPCEcho> native_;
};
IPCEchoBindings::IPCEchoBindings(base::WeakPtr<IPCEcho> native)
: native_(native) {
}
void IPCEchoBindings::RequestEcho(int id, int size) {
if (!native_)
return;
native_->RequestEcho(id, size);
}
int IPCEchoBindings::GetLastEchoId() const {
if (!native_)
return 0;
return native_->last_echo_id();
}
int IPCEchoBindings::GetLastEchoSize() const {
if (!native_)
return 0;
return native_->last_echo_size();
}
gin::WrapperInfo IPCEchoBindings::kWrapperInfo = {
gin::kEmbedderNativeGin };
gin::ObjectTemplateBuilder IPCEchoBindings::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return gin::Wrappable<IPCEchoBindings>::GetObjectTemplateBuilder(isolate)
.SetMethod("requestEcho",
&IPCEchoBindings::RequestEcho)
.SetProperty("lastEchoId",
&IPCEchoBindings::GetLastEchoId)
.SetProperty("lastEchoSize",
&IPCEchoBindings::GetLastEchoSize);
}
// static
void IPCEchoBindings::Install(base::WeakPtr<IPCEcho> echo,
blink::WebFrame* frame) {
std::vector<std::string> names;
names.push_back("ipcEcho");
return InstallAsWindowProperties(
new IPCEchoBindings(echo), frame, names);
}
IPCEcho::IPCEcho(blink::WebDocument document,
IPC::Sender* sender,
int routing_id)
: weak_factory_(this),
document_(document), sender_(sender), routing_id_(routing_id),
last_echo_id_(0) {
}
IPCEcho::~IPCEcho() {
}
void IPCEcho::RequestEcho(int id, int size) {
sender_->Send(new ShellViewHostMsg_EchoPing(
routing_id_, id, std::string(size, '*')));
}
void IPCEcho::DidRespondEcho(int id, int size) {
last_echo_id_ = id;
last_echo_size_ = size;
blink::WebString eventName = blink::WebString::fromUTF8("CustomEvent");
blink::WebString eventType = blink::WebString::fromUTF8("pong");
blink::WebDOMEvent event = document_.createEvent(eventName);
event.to<blink::WebDOMCustomEvent>().initCustomEvent(
eventType, false, false, blink::WebSerializedScriptValue());
document_.dispatchEvent(event);
}
void IPCEcho::Install(blink::WebFrame* frame) {
IPCEchoBindings::Install(weak_factory_.GetWeakPtr(), frame);
}
} // namespace content
// Copyright 2014 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.
#ifndef CONTENT_SHELL_IPC_ECHO_H_
#define CONTENT_SHELL_IPC_ECHO_H_
#include <utility>
#include <vector>
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
#include "third_party/WebKit/public/web/WebDocument.h"
namespace blink {
class WebFrame;
}
namespace IPC {
class Sender;
}
namespace content {
// This class is for writing micro benchmarks exercising underlying
// IPC::Channel using HTML and JavaScript.
//
// TODO(morrita): The benchmark effort tries to makesure that
// IPC::ChannelMojo is as performant as native IPC::Channel
// implementations. Currently IPC::ChannelMojo is hidden behind
// "--enable-renderer-mojo-channel". Once it is turned on by default.
// we no longer need this class and should remove it.
class IPCEcho : public base::SupportsWeakPtr<IPCEcho> {
public:
IPCEcho(blink::WebDocument document, IPC::Sender* sender, int routing_id);
~IPCEcho();
void RequestEcho(int id, int size);
void DidRespondEcho(int id, int size);
void Install(blink::WebFrame*);
int last_echo_id() const { return last_echo_id_; }
int last_echo_size() const { return last_echo_size_; }
base::WeakPtrFactory<IPCEcho> weak_factory_;
blink::WebDocument document_;
IPC::Sender* sender_;
int routing_id_;
int last_echo_id_;
int last_echo_size_;
};
} // namespace content
#endif // CONTENT_SHELL_IPC_ECHO_DISPATCHER_H_
...@@ -5,9 +5,12 @@ ...@@ -5,9 +5,12 @@
#include "content/shell/renderer/shell_render_view_observer.h" #include "content/shell/renderer/shell_render_view_observer.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h" #include "content/public/renderer/render_view.h"
#include "content/public/renderer/render_view_observer.h" #include "content/public/renderer/render_view_observer.h"
#include "content/shell/common/shell_messages.h"
#include "content/shell/common/shell_switches.h" #include "content/shell/common/shell_switches.h"
#include "content/shell/renderer/ipc_echo.h"
#include "third_party/WebKit/public/web/WebTestingSupport.h" #include "third_party/WebKit/public/web/WebTestingSupport.h"
#include "third_party/WebKit/public/web/WebView.h" #include "third_party/WebKit/public/web/WebView.h"
...@@ -17,12 +20,38 @@ ShellRenderViewObserver::ShellRenderViewObserver(RenderView* render_view) ...@@ -17,12 +20,38 @@ ShellRenderViewObserver::ShellRenderViewObserver(RenderView* render_view)
: RenderViewObserver(render_view) { : RenderViewObserver(render_view) {
} }
ShellRenderViewObserver::~ShellRenderViewObserver() {
}
void ShellRenderViewObserver::DidClearWindowObject( void ShellRenderViewObserver::DidClearWindowObject(
blink::WebLocalFrame* frame) { blink::WebLocalFrame* frame) {
if (CommandLine::ForCurrentProcess()->HasSwitch( if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kExposeInternalsForTesting)) { switches::kExposeInternalsForTesting)) {
blink::WebTestingSupport::injectInternalsObject(frame); blink::WebTestingSupport::injectInternalsObject(frame);
} }
if (CommandLine::ForCurrentProcess()->HasSwitch(
switches::kExposeIpcEcho)) {
RenderView* view = render_view();
if (!ipc_echo_)
ipc_echo_.reset(new IPCEcho(view->GetWebView()->mainFrame()->document(),
RenderThread::Get(), view->GetRoutingID()));
ipc_echo_->Install(view->GetWebView()->mainFrame());
}
}
bool ShellRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ShellRenderViewObserver, message)
IPC_MESSAGE_HANDLER(ShellViewMsg_EchoPong, OnEchoPong)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void ShellRenderViewObserver::OnEchoPong(int id, const std::string& body) {
ipc_echo_->DidRespondEcho(id, body.size());
} }
} // namespace content } // namespace content
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CONTENT_SHELL_SHELL_RENDER_VIEW_OBSERVER_H_ #ifndef CONTENT_SHELL_SHELL_RENDER_VIEW_OBSERVER_H_
#define CONTENT_SHELL_SHELL_RENDER_VIEW_OBSERVER_H_ #define CONTENT_SHELL_SHELL_RENDER_VIEW_OBSERVER_H_
#include <string>
#include "base/memory/scoped_ptr.h"
#include "content/public/renderer/render_view_observer.h" #include "content/public/renderer/render_view_observer.h"
namespace blink { namespace blink {
...@@ -13,18 +15,24 @@ class WebFrame; ...@@ -13,18 +15,24 @@ class WebFrame;
namespace content { namespace content {
class IPCEcho;
class RenderView; class RenderView;
class ShellRenderViewObserver : public RenderViewObserver { class ShellRenderViewObserver : public RenderViewObserver {
public: public:
explicit ShellRenderViewObserver(RenderView* render_view); explicit ShellRenderViewObserver(RenderView* render_view);
virtual ~ShellRenderViewObserver() {} virtual ~ShellRenderViewObserver();
private: private:
// Message handlers.
void OnEchoPong(int id, const std::string& body);
// RenderViewObserver implementation. // RenderViewObserver implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void DidClearWindowObject(blink::WebLocalFrame* frame) OVERRIDE; virtual void DidClearWindowObject(blink::WebLocalFrame* frame) OVERRIDE;
scoped_ptr<IPCEcho> ipc_echo_;
DISALLOW_COPY_AND_ASSIGN(ShellRenderViewObserver); DISALLOW_COPY_AND_ASSIGN(ShellRenderViewObserver);
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "content/shell/common/test_runner/test_preferences.h" #include "content/shell/common/test_runner/test_preferences.h"
#include "content/shell/renderer/binding_helpers.h"
#include "content/shell/renderer/test_runner/WebTestDelegate.h" #include "content/shell/renderer/test_runner/WebTestDelegate.h"
#include "content/shell/renderer/test_runner/mock_web_push_client.h" #include "content/shell/renderer/test_runner/mock_web_push_client.h"
#include "content/shell/renderer/test_runner/mock_web_speech_recognizer.h" #include "content/shell/renderer/test_runner/mock_web_speech_recognizer.h"
...@@ -313,22 +314,11 @@ gin::WrapperInfo TestRunnerBindings::kWrapperInfo = { ...@@ -313,22 +314,11 @@ gin::WrapperInfo TestRunnerBindings::kWrapperInfo = {
// static // static
void TestRunnerBindings::Install(base::WeakPtr<TestRunner> runner, void TestRunnerBindings::Install(base::WeakPtr<TestRunner> runner,
WebFrame* frame) { WebFrame* frame) {
v8::Isolate* isolate = blink::mainThreadIsolate(); std::vector<std::string> names;
v8::HandleScope handle_scope(isolate); names.push_back("testRunner");
v8::Handle<v8::Context> context = frame->mainWorldScriptContext(); names.push_back("layoutTestController");
if (context.IsEmpty()) return InstallAsWindowProperties(
return; new TestRunnerBindings(runner), frame, names);
v8::Context::Scope context_scope(context);
gin::Handle<TestRunnerBindings> bindings =
gin::CreateHandle(isolate, new TestRunnerBindings(runner));
if (bindings.IsEmpty())
return;
v8::Handle<v8::Object> global = context->Global();
v8::Handle<v8::Value> v8_bindings = bindings.ToV8();
global->Set(gin::StringToV8(isolate, "testRunner"), v8_bindings);
global->Set(gin::StringToV8(isolate, "layoutTestController"), v8_bindings);
} }
TestRunnerBindings::TestRunnerBindings(base::WeakPtr<TestRunner> runner) TestRunnerBindings::TestRunnerBindings(base::WeakPtr<TestRunner> runner)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment