[inspector] added inspector test runner [part 2]
- added the channel implementation, - added inspector implementation, - added v8::Extension for communication between backend and frontend. BUG=chromium:635948 R=dgozman@chromium.org,alph@chromium.org Committed: https://crrev.com/cceaa1225c6a96a28d2c7410d1db520423fb8c31 Review-Url: https://codereview.chromium.org/2368393003 Cr-Original-Commit-Position: refs/heads/master@{#39888} Cr-Commit-Position: refs/heads/master@{#39928}
This commit is contained in:
parent
fad5dd827d
commit
751814a128
@ -8,6 +8,8 @@ v8_executable("inspector-test") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"inspector-impl.cc",
|
||||
"inspector-impl.h",
|
||||
"task-runner.cc",
|
||||
"task-runner.h",
|
||||
]
|
||||
|
152
test/inspector/inspector-impl.cc
Normal file
152
test/inspector/inspector-impl.cc
Normal file
@ -0,0 +1,152 @@
|
||||
// Copyright 2016 the V8 project 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 "test/inspector/inspector-impl.h"
|
||||
|
||||
#include "include/v8.h"
|
||||
#include "src/inspector/string-16.h"
|
||||
|
||||
namespace {
|
||||
|
||||
const int kInspectorClientIndex = v8::Context::kDebugIdIndex + 1;
|
||||
|
||||
class ChannelImpl final : public v8_inspector::V8Inspector::Channel {
|
||||
public:
|
||||
explicit ChannelImpl(InspectorClientImpl::FrontendChannel* frontend_channel)
|
||||
: frontend_channel_(frontend_channel) {}
|
||||
virtual ~ChannelImpl() = default;
|
||||
|
||||
private:
|
||||
void sendProtocolResponse(int callId,
|
||||
const v8_inspector::StringView& message) override {
|
||||
frontend_channel_->SendMessageToFrontend(message);
|
||||
}
|
||||
void sendProtocolNotification(
|
||||
const v8_inspector::StringView& message) override {
|
||||
frontend_channel_->SendMessageToFrontend(message);
|
||||
}
|
||||
void flushProtocolNotifications() override {}
|
||||
|
||||
InspectorClientImpl::FrontendChannel* frontend_channel_;
|
||||
DISALLOW_COPY_AND_ASSIGN(ChannelImpl);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class ConnectTask : public TaskRunner::Task {
|
||||
public:
|
||||
ConnectTask(InspectorClientImpl* client, v8::base::Semaphore* ready_semaphore)
|
||||
: client_(client), ready_semaphore_(ready_semaphore) {}
|
||||
virtual ~ConnectTask() = default;
|
||||
|
||||
bool is_inspector_task() final { return true; }
|
||||
|
||||
void Run(v8::Isolate* isolate,
|
||||
const v8::Global<v8::Context>& global_context) {
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> context = global_context.Get(isolate);
|
||||
client_->connect(context);
|
||||
if (ready_semaphore_) ready_semaphore_->Signal();
|
||||
}
|
||||
|
||||
private:
|
||||
InspectorClientImpl* client_;
|
||||
v8::base::Semaphore* ready_semaphore_;
|
||||
};
|
||||
|
||||
InspectorClientImpl::InspectorClientImpl(TaskRunner* task_runner,
|
||||
FrontendChannel* frontend_channel,
|
||||
v8::base::Semaphore* ready_semaphore)
|
||||
: isolate_(nullptr),
|
||||
task_runner_(task_runner),
|
||||
frontend_channel_(frontend_channel) {
|
||||
task_runner_->Append(new ConnectTask(this, ready_semaphore));
|
||||
}
|
||||
|
||||
InspectorClientImpl::~InspectorClientImpl() {}
|
||||
|
||||
void InspectorClientImpl::connect(v8::Local<v8::Context> context) {
|
||||
isolate_ = context->GetIsolate();
|
||||
channel_.reset(new ChannelImpl(frontend_channel_));
|
||||
|
||||
inspector_ = v8_inspector::V8Inspector::create(isolate_, this);
|
||||
session_ = inspector_->connect(1, channel_.get(), v8_inspector::StringView());
|
||||
|
||||
context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this);
|
||||
inspector_->contextCreated(
|
||||
v8_inspector::V8ContextInfo(context, 1, v8_inspector::StringView()));
|
||||
context_.Reset(isolate_, context);
|
||||
}
|
||||
|
||||
v8::Local<v8::Context> InspectorClientImpl::ensureDefaultContextInGroup(int) {
|
||||
CHECK(isolate_);
|
||||
return context_.Get(isolate_);
|
||||
}
|
||||
|
||||
double InspectorClientImpl::currentTimeMS() {
|
||||
return v8::base::OS::TimeCurrentMillis();
|
||||
}
|
||||
|
||||
void InspectorClientImpl::runMessageLoopOnPause(int) {
|
||||
task_runner_->RunMessageLoop(true);
|
||||
}
|
||||
|
||||
void InspectorClientImpl::quitMessageLoopOnPause() {
|
||||
task_runner_->QuitMessageLoop();
|
||||
}
|
||||
|
||||
v8_inspector::V8InspectorSession* InspectorClientImpl::SessionFromContext(
|
||||
v8::Local<v8::Context> context) {
|
||||
InspectorClientImpl* inspector_client = static_cast<InspectorClientImpl*>(
|
||||
context->GetAlignedPointerFromEmbedderData(kInspectorClientIndex));
|
||||
CHECK(inspector_client);
|
||||
return inspector_client->session_.get();
|
||||
}
|
||||
|
||||
class SendMessageToBackendTask : public TaskRunner::Task {
|
||||
public:
|
||||
explicit SendMessageToBackendTask(const v8_inspector::String16& message)
|
||||
: message_(message) {}
|
||||
|
||||
bool is_inspector_task() final { return true; }
|
||||
|
||||
void Run(v8::Isolate* isolate,
|
||||
const v8::Global<v8::Context>& global_context) override {
|
||||
v8_inspector::V8InspectorSession* session = nullptr;
|
||||
{
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> context = global_context.Get(isolate);
|
||||
session = InspectorClientImpl::SessionFromContext(context);
|
||||
CHECK(session);
|
||||
}
|
||||
v8_inspector::StringView message_view(
|
||||
reinterpret_cast<const uint16_t*>(message_.characters16()),
|
||||
message_.length());
|
||||
session->dispatchProtocolMessage(message_view);
|
||||
}
|
||||
|
||||
private:
|
||||
v8_inspector::String16 message_;
|
||||
};
|
||||
|
||||
TaskRunner* SendMessageToBackendExtension::backend_task_runner_ = nullptr;
|
||||
|
||||
v8::Local<v8::FunctionTemplate>
|
||||
SendMessageToBackendExtension::GetNativeFunctionTemplate(
|
||||
v8::Isolate* isolate, v8::Local<v8::String> name) {
|
||||
return v8::FunctionTemplate::New(
|
||||
isolate, SendMessageToBackendExtension::SendMessageToBackend);
|
||||
}
|
||||
|
||||
void SendMessageToBackendExtension::SendMessageToBackend(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
CHECK(backend_task_runner_);
|
||||
CHECK(args.Length() == 1 && args[0]->IsString());
|
||||
v8::Local<v8::String> message = args[0].As<v8::String>();
|
||||
std::unique_ptr<uint16_t[]> buffer(new uint16_t[message->Length()]);
|
||||
message.As<v8::String>()->Write(reinterpret_cast<uint16_t*>(buffer.get()), 0,
|
||||
message->Length());
|
||||
v8_inspector::String16 message_string(buffer.get(), message->Length());
|
||||
backend_task_runner_->Append(new SendMessageToBackendTask(message_string));
|
||||
}
|
76
test/inspector/inspector-impl.h
Normal file
76
test/inspector/inspector-impl.h
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright 2016 the V8 project 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 V8_TEST_INSPECTOR_PROTOCOL_INSPECTOR_IMPL_H_
|
||||
#define V8_TEST_INSPECTOR_PROTOCOL_INSPECTOR_IMPL_H_
|
||||
|
||||
#include "include/v8-inspector.h"
|
||||
#include "include/v8.h"
|
||||
#include "src/base/macros.h"
|
||||
#include "src/base/platform/platform.h"
|
||||
#include "test/inspector/task-runner.h"
|
||||
|
||||
class InspectorClientImpl : public v8_inspector::V8InspectorClient {
|
||||
public:
|
||||
class FrontendChannel {
|
||||
public:
|
||||
virtual ~FrontendChannel() = default;
|
||||
virtual void SendMessageToFrontend(
|
||||
const v8_inspector::StringView& message) = 0;
|
||||
};
|
||||
|
||||
InspectorClientImpl(TaskRunner* task_runner,
|
||||
FrontendChannel* frontend_channel,
|
||||
v8::base::Semaphore* ready_semaphore);
|
||||
virtual ~InspectorClientImpl();
|
||||
|
||||
private:
|
||||
// V8InspectorClient implementation.
|
||||
v8::Local<v8::Context> ensureDefaultContextInGroup(
|
||||
int context_group_id) override;
|
||||
double currentTimeMS() override;
|
||||
void runMessageLoopOnPause(int context_group_id) override;
|
||||
void quitMessageLoopOnPause() override;
|
||||
|
||||
static v8_inspector::V8InspectorSession* SessionFromContext(
|
||||
v8::Local<v8::Context> context);
|
||||
|
||||
friend class SendMessageToBackendTask;
|
||||
|
||||
friend class ConnectTask;
|
||||
void connect(v8::Local<v8::Context> context);
|
||||
|
||||
std::unique_ptr<v8_inspector::V8Inspector> inspector_;
|
||||
std::unique_ptr<v8_inspector::V8InspectorSession> session_;
|
||||
std::unique_ptr<v8_inspector::V8Inspector::Channel> channel_;
|
||||
|
||||
v8::Isolate* isolate_;
|
||||
v8::Global<v8::Context> context_;
|
||||
|
||||
TaskRunner* task_runner_;
|
||||
FrontendChannel* frontend_channel_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(InspectorClientImpl);
|
||||
};
|
||||
|
||||
class SendMessageToBackendExtension : public v8::Extension {
|
||||
public:
|
||||
SendMessageToBackendExtension()
|
||||
: v8::Extension("v8_inspector/frontend",
|
||||
"native function sendMessageToBackend();") {}
|
||||
virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate(
|
||||
v8::Isolate* isolate, v8::Local<v8::String> name);
|
||||
|
||||
static void set_backend_task_runner(TaskRunner* task_runner) {
|
||||
backend_task_runner_ = task_runner;
|
||||
}
|
||||
|
||||
private:
|
||||
static void SendMessageToBackend(
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
static TaskRunner* backend_task_runner_;
|
||||
};
|
||||
|
||||
#endif // V8_TEST_INSPECTOR_PROTOCOL_INSPECTOR_IMPL_H_
|
@ -6,6 +6,8 @@
|
||||
'variables': {
|
||||
'v8_code': 1,
|
||||
'inspector_protocol_sources': [
|
||||
'inspector-impl.cc',
|
||||
'inspector-impl.h',
|
||||
'task-runner.cc',
|
||||
'task-runner.h',
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user