Roll inspector-protocol to c22d4bd88fb7a39bc41c3b1adcdd733cc9b5e8ea

R=dgozman

Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I5fd64b95772ed061c0a432431a6e5273e5d44790
Reviewed-on: https://chromium-review.googlesource.com/1149321
Commit-Queue: Andrey Lushnikov <lushnikov@chromium.org>
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55180}
This commit is contained in:
Andrey Lushnikov 2018-07-24 17:17:11 -07:00 committed by Commit Bot
parent 81837c341a
commit 494531984e
7 changed files with 96 additions and 115 deletions

View File

@ -170,6 +170,12 @@ void V8InspectorSessionImpl::sendProtocolNotification(
m_channel->sendNotification(MessageBuffer::create(std::move(message)));
}
void V8InspectorSessionImpl::fallThrough(int callId, const String16& method,
const String16& message) {
// There's no other layer to handle the command.
UNREACHABLE();
}
void V8InspectorSessionImpl::flushProtocolNotifications() {
m_channel->flushProtocolNotifications();
}
@ -313,7 +319,15 @@ void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) {
void V8InspectorSessionImpl::dispatchProtocolMessage(
const StringView& message) {
m_dispatcher.dispatch(protocol::StringUtil::parseJSON(message));
int callId;
String16 method;
std::unique_ptr<protocol::Value> parsedMessage =
protocol::StringUtil::parseJSON(message);
if (m_dispatcher.parseCommand(parsedMessage.get(), &callId, &method)) {
// Pass empty string instead of the actual message to save on a conversion.
// We're allowed to do so because fall-through is not implemented.
m_dispatcher.dispatch(callId, method, std::move(parsedMessage), "");
}
}
std::unique_ptr<StringBuffer> V8InspectorSessionImpl::stateJSON() {

View File

@ -101,6 +101,8 @@ class V8InspectorSessionImpl : public V8InspectorSession,
int callId, std::unique_ptr<protocol::Serializable> message) override;
void sendProtocolNotification(
std::unique_ptr<protocol::Serializable> message) override;
void fallThrough(int callId, const String16& method,
const String16& message) override;
void flushProtocolNotifications() override;
int m_contextGroupId;

View File

@ -2,7 +2,7 @@ Name: inspector protocol
Short Name: inspector_protocol
URL: https://chromium.googlesource.com/deps/inspector_protocol/
Version: 0
Revision: 0d4255502019144a5dec5669d7992165ae8924e7
Revision: c22d4bd88fb7a39bc41c3b1adcdd733cc9b5e8ea
License: BSD
License File: LICENSE
Security Critical: no

View File

@ -68,10 +68,11 @@ DispatcherBase::WeakPtr::~WeakPtr()
m_dispatcher->m_weakPtrs.erase(this);
}
DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, int callbackId)
DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const String& message)
: m_backendImpl(std::move(backendImpl))
, m_callId(callId)
, m_callbackId(callbackId) { }
, m_method(method)
, m_message(message) { }
DispatcherBase::Callback::~Callback() = default;
@ -92,32 +93,18 @@ void DispatcherBase::Callback::fallThroughIfActive()
{
if (!m_backendImpl || !m_backendImpl->get())
return;
m_backendImpl->get()->markFallThrough(m_callbackId);
m_backendImpl->get()->channel()->fallThrough(m_callId, m_method, m_message);
m_backendImpl = nullptr;
}
DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel)
: m_frontendChannel(frontendChannel)
, m_lastCallbackId(0)
, m_lastCallbackFallThrough(false) { }
: m_frontendChannel(frontendChannel) { }
DispatcherBase::~DispatcherBase()
{
clearFrontend();
}
int DispatcherBase::nextCallbackId()
{
m_lastCallbackFallThrough = false;
return ++m_lastCallbackId;
}
void DispatcherBase::markFallThrough(int callbackId)
{
DCHECK(callbackId == m_lastCallbackId);
m_lastCallbackFallThrough = true;
}
void DispatcherBase::sendResponse(int callId, const DispatchResponse& response, std::unique_ptr<protocol::DictionaryValue> result)
{
if (!m_frontendChannel)
@ -218,13 +205,7 @@ std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr()
}
UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel)
: m_frontendChannel(frontendChannel)
, m_fallThroughForNotFound(false) { }
void UberDispatcher::setFallThroughForNotFound(bool fallThroughForNotFound)
{
m_fallThroughForNotFound = fallThroughForNotFound;
}
: m_frontendChannel(frontendChannel) { }
void UberDispatcher::registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase> dispatcher)
{
@ -237,81 +218,70 @@ void UberDispatcher::setupRedirects(const std::unordered_map<String, String>& re
m_redirects[pair.first] = pair.second;
}
DispatchResponse::Status UberDispatcher::dispatch(std::unique_ptr<Value> parsedMessage, int* outCallId, String* outMethod)
{
bool UberDispatcher::parseCommand(Value* parsedMessage, int* outCallId, String* outMethod) {
if (!parsedMessage) {
reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
return DispatchResponse::kError;
return false;
}
std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
protocol::DictionaryValue* messageObject = DictionaryValue::cast(parsedMessage);
if (!messageObject) {
reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
return DispatchResponse::kError;
return false;
}
int callId = 0;
protocol::Value* callIdValue = messageObject->get("id");
bool success = callIdValue && callIdValue->asInteger(&callId);
if (outCallId)
*outCallId = callId;
if (!success) {
reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have integer 'id' property");
return DispatchResponse::kError;
return false;
}
if (outCallId)
*outCallId = callId;
protocol::Value* methodValue = messageObject->get("method");
String method;
success = methodValue && methodValue->asString(&method);
if (outMethod)
*outMethod = method;
if (!success) {
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kInvalidRequest, "Message must have string 'method' property", nullptr);
return DispatchResponse::kError;
return false;
}
std::unordered_map<String, String>::iterator redirectIt = m_redirects.find(method);
if (redirectIt != m_redirects.end())
method = redirectIt->second;
size_t dotIndex = StringUtil::find(method, ".");
if (dotIndex == StringUtil::kNotFound) {
if (m_fallThroughForNotFound)
return DispatchResponse::kFallThrough;
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
return DispatchResponse::kError;
}
String domain = StringUtil::substring(method, 0, dotIndex);
auto it = m_dispatchers.find(domain);
if (it == m_dispatchers.end()) {
if (m_fallThroughForNotFound)
return DispatchResponse::kFallThrough;
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
return DispatchResponse::kError;
}
return it->second->dispatch(callId, method, std::move(messageObject));
if (outMethod)
*outMethod = method;
return true;
}
bool UberDispatcher::getCommandName(const String& message, String* method, std::unique_ptr<protocol::DictionaryValue>* parsedMessage)
protocol::DispatcherBase* UberDispatcher::findDispatcher(const String& method) {
size_t dotIndex = StringUtil::find(method, ".");
if (dotIndex == StringUtil::kNotFound)
return nullptr;
String domain = StringUtil::substring(method, 0, dotIndex);
auto it = m_dispatchers.find(domain);
if (it == m_dispatchers.end())
return nullptr;
if (!it->second->canDispatch(method))
return nullptr;
return it->second.get();
}
bool UberDispatcher::canDispatch(const String& method)
{
std::unique_ptr<protocol::Value> value = StringUtil::parseJSON(message);
if (!value) {
reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kParseError, "Message must be a valid JSON");
return false;
}
return !!findDispatcher(method);
}
protocol::DictionaryValue* object = DictionaryValue::cast(value.get());
if (!object) {
reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must be an object");
return false;
void UberDispatcher::dispatch(int callId, const String& method, std::unique_ptr<Value> parsedMessage, const String& rawMessage)
{
protocol::DispatcherBase* dispatcher = findDispatcher(method);
if (!dispatcher) {
reportProtocolErrorTo(m_frontendChannel, callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
return;
}
if (!object->getString("method", method)) {
reportProtocolErrorTo(m_frontendChannel, DispatchResponse::kInvalidRequest, "Message must have string 'method' property");
return false;
}
parsedMessage->reset(DictionaryValue::cast(value.release()));
return true;
std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage));
dispatcher->dispatch(callId, method, rawMessage, std::move(messageObject));
}
UberDispatcher::~UberDispatcher() = default;

View File

@ -20,8 +20,7 @@ public:
enum Status {
kSuccess = 0,
kError = 1,
kFallThrough = 2,
kAsync = 3
kFallThrough = 2
};
enum ErrorCode {
@ -67,7 +66,7 @@ public:
class {{config.lib.export_macro}} Callback {
public:
Callback(std::unique_ptr<WeakPtr> backendImpl, int callId, int callbackId);
Callback(std::unique_ptr<WeakPtr> backendImpl, int callId, const String& method, const String& message);
virtual ~Callback();
void dispose();
@ -78,13 +77,16 @@ public:
private:
std::unique_ptr<WeakPtr> m_backendImpl;
int m_callId;
int m_callbackId;
String m_method;
String m_message;
};
explicit DispatcherBase(FrontendChannel*);
virtual ~DispatcherBase();
virtual DispatchResponse::Status dispatch(int callId, const String& method, std::unique_ptr<protocol::DictionaryValue> messageObject) = 0;
virtual bool canDispatch(const String& method) = 0;
virtual void dispatch(int callId, const String& method, const String& rawMessage, std::unique_ptr<protocol::DictionaryValue> messageObject) = 0;
FrontendChannel* channel() { return m_frontendChannel; }
void sendResponse(int callId, const DispatchResponse&, std::unique_ptr<protocol::DictionaryValue> result);
void sendResponse(int callId, const DispatchResponse&);
@ -94,15 +96,9 @@ public:
std::unique_ptr<WeakPtr> weakPtr();
int nextCallbackId();
void markFallThrough(int callbackId);
bool lastCallbackFallThrough() { return m_lastCallbackFallThrough; }
private:
FrontendChannel* m_frontendChannel;
std::unordered_set<WeakPtr*> m_weakPtrs;
int m_lastCallbackId;
bool m_lastCallbackFallThrough;
};
class {{config.lib.export_macro}} UberDispatcher {
@ -111,16 +107,15 @@ public:
explicit UberDispatcher(FrontendChannel*);
void registerBackend(const String& name, std::unique_ptr<protocol::DispatcherBase>);
void setupRedirects(const std::unordered_map<String, String>&);
DispatchResponse::Status dispatch(std::unique_ptr<Value> message, int* callId = nullptr, String* method = nullptr);
bool parseCommand(Value* message, int* callId, String* method);
bool canDispatch(const String& method);
void dispatch(int callId, const String& method, std::unique_ptr<Value> message, const String& rawMessage);
FrontendChannel* channel() { return m_frontendChannel; }
bool fallThroughForNotFound() { return m_fallThroughForNotFound; }
void setFallThroughForNotFound(bool);
bool getCommandName(const String& message, String* method, std::unique_ptr<protocol::DictionaryValue>* parsedMessage);
virtual ~UberDispatcher();
private:
protocol::DispatcherBase* findDispatcher(const String& method);
FrontendChannel* m_frontendChannel;
bool m_fallThroughForNotFound;
std::unordered_map<String, String> m_redirects;
std::unordered_map<String, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers;
};

View File

@ -20,6 +20,7 @@ public:
virtual ~FrontendChannel() { }
virtual void sendProtocolResponse(int callId, std::unique_ptr<Serializable> message) = 0;
virtual void sendProtocolNotification(std::unique_ptr<Serializable> message) = 0;
virtual void fallThrough(int callId, const String& method, const String& message) = 0;
virtual void flushProtocolNotifications() = 0;
};

View File

@ -196,10 +196,9 @@ void Frontend::sendRawNotification(const String& notification)
class DispatcherImpl : public protocol::DispatcherBase {
public:
DispatcherImpl(FrontendChannel* frontendChannel, Backend* backend, bool fallThroughForNotFound)
DispatcherImpl(FrontendChannel* frontendChannel, Backend* backend)
: DispatcherBase(frontendChannel)
, m_backend(backend)
, m_fallThroughForNotFound(fallThroughForNotFound) {
, m_backend(backend) {
{% for command in domain.commands %}
{% if "redirect" in command %}
m_redirects["{{domain.domain}}.{{command.name}}"] = "{{command.redirect}}.{{command.name}}";
@ -210,11 +209,12 @@ public:
{% endfor %}
}
~DispatcherImpl() override { }
DispatchResponse::Status dispatch(int callId, const String& method, std::unique_ptr<protocol::DictionaryValue> messageObject) override;
bool canDispatch(const String& method) override;
void dispatch(int callId, const String& method, const String& message, std::unique_ptr<protocol::DictionaryValue> messageObject) override;
std::unordered_map<String, String>& redirects() { return m_redirects; }
protected:
using CallHandler = DispatchResponse::Status (DispatcherImpl::*)(int callId, std::unique_ptr<DictionaryValue> messageObject, ErrorSupport* errors);
using CallHandler = void (DispatcherImpl::*)(int callId, const String& method, const String& message, std::unique_ptr<DictionaryValue> messageObject, ErrorSupport* errors);
using DispatchMap = std::unordered_map<String, CallHandler>;
DispatchMap m_dispatchMap;
std::unordered_map<String, String> m_redirects;
@ -222,25 +222,22 @@ protected:
{% for command in domain.commands %}
{% if "redirect" in command %}{% continue %}{% endif %}
{% if not protocol.generate_command(domain.domain, command.name) %}{% continue %}{% endif %}
DispatchResponse::Status {{command.name}}(int callId, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport*);
void {{command.name}}(int callId, const String& method, const String& message, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport*);
{% endfor %}
Backend* m_backend;
bool m_fallThroughForNotFound;
};
DispatchResponse::Status DispatcherImpl::dispatch(int callId, const String& method, std::unique_ptr<protocol::DictionaryValue> messageObject)
bool DispatcherImpl::canDispatch(const String& method) {
return m_dispatchMap.find(method) != m_dispatchMap.end();
}
void DispatcherImpl::dispatch(int callId, const String& method, const String& message, std::unique_ptr<protocol::DictionaryValue> messageObject)
{
std::unordered_map<String, CallHandler>::iterator it = m_dispatchMap.find(method);
if (it == m_dispatchMap.end()) {
if (m_fallThroughForNotFound)
return DispatchResponse::kFallThrough;
reportProtocolError(callId, DispatchResponse::kMethodNotFound, "'" + method + "' wasn't found", nullptr);
return DispatchResponse::kError;
}
DCHECK(it != m_dispatchMap.end());
protocol::ErrorSupport errors;
return (this->*(it->second))(callId, std::move(messageObject), &errors);
(this->*(it->second))(callId, method, message, std::move(messageObject), &errors);
}
{% for command in domain.commands %}
@ -251,8 +248,8 @@ DispatchResponse::Status DispatcherImpl::dispatch(int callId, const String& meth
class {{command_name_title}}CallbackImpl : public Backend::{{command_name_title}}Callback, public DispatcherBase::Callback {
public:
{{command_name_title}}CallbackImpl(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, int callbackId)
: DispatcherBase::Callback(std::move(backendImpl), callId, callbackId) { }
{{command_name_title}}CallbackImpl(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId, const String& method, const String& message)
: DispatcherBase::Callback(std::move(backendImpl), callId, method, message) { }
void sendSuccess(
{%- for parameter in command.returns -%}
@ -289,7 +286,7 @@ public:
};
{% endif %}
DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport* errors)
void DispatcherImpl::{{command.name}}(int callId, const String& method, const String& message, std::unique_ptr<DictionaryValue> requestMessageObject, ErrorSupport* errors)
{
{% if "parameters" in command %}
// Prepare input parameters.
@ -312,7 +309,7 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
errors->pop();
if (errors->hasErrors()) {
reportProtocolError(callId, DispatchResponse::kInvalidParams, kInvalidParamsString, errors);
return DispatchResponse::kError;
return;
}
{% endif %}
{% if "returns" in command and not protocol.is_async_command(domain.domain, command.name) %}
@ -343,8 +340,10 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
&out_{{parameter.name}}
{%- endfor %}
{% endif %});
if (response.status() == DispatchResponse::kFallThrough)
return response.status();
if (response.status() == DispatchResponse::kFallThrough) {
channel()->fallThrough(callId, method, message);
return;
}
{% if "returns" in command %}
std::unique_ptr<protocol::DictionaryValue> result = DictionaryValue::create();
if (response.status() == DispatchResponse::kSuccess) {
@ -363,10 +362,10 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
if (weak->get())
weak->get()->sendResponse(callId, response);
{% endif %}
return response.status();
return;
{% else %}
std::unique_ptr<DispatcherBase::WeakPtr> weak = weakPtr();
std::unique_ptr<{{command_name_title}}CallbackImpl> callback(new {{command.name | to_title_case}}CallbackImpl(weakPtr(), callId, nextCallbackId()));
std::unique_ptr<{{command_name_title}}CallbackImpl> callback(new {{command.name | to_title_case}}CallbackImpl(weakPtr(), callId, method, message));
m_backend->{{command.name | to_method_case}}(
{%- for property in command.parameters -%}
{%- if not loop.first -%}, {% endif -%}
@ -378,7 +377,7 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
{%- endfor -%}
{%- if command.parameters -%}, {% endif -%}
std::move(callback));
return (weak->get() && weak->get()->lastCallbackFallThrough()) ? DispatchResponse::kFallThrough : DispatchResponse::kAsync;
return;
{% endif %}
}
{% endfor %}
@ -386,7 +385,7 @@ DispatchResponse::Status DispatcherImpl::{{command.name}}(int callId, std::uniqu
// static
void Dispatcher::wire(UberDispatcher* uber, Backend* backend)
{
std::unique_ptr<DispatcherImpl> dispatcher(new DispatcherImpl(uber->channel(), backend, uber->fallThroughForNotFound()));
std::unique_ptr<DispatcherImpl> dispatcher(new DispatcherImpl(uber->channel(), backend));
uber->setupRedirects(dispatcher->redirects());
uber->registerBackend("{{domain.domain}}", std::move(dispatcher));
}