| OLD | NEW |
| (Empty) |
| 1 // This file is generated | |
| 2 | |
| 3 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | |
| 4 // Use of this source code is governed by a BSD-style license that can be | |
| 5 // found in the LICENSE file. | |
| 6 | |
| 7 #include "platform/inspector_protocol/{{class_name}}.h" | |
| 8 | |
| 9 #include "platform/inspector_protocol/Collections.h" | |
| 10 #include "platform/inspector_protocol/FrontendChannel.h" | |
| 11 #include "platform/inspector_protocol/Parser.h" | |
| 12 | |
| 13 namespace blink { | |
| 14 namespace protocol { | |
| 15 | |
| 16 using protocol::Maybe; | |
| 17 | |
| 18 class DispatcherImpl; | |
| 19 | |
| 20 class DispatcherImplWeakPtr { | |
| 21 public: | |
| 22 DispatcherImplWeakPtr(DispatcherImpl* dispatcher) : m_dispatcher(dispatcher)
{ } | |
| 23 ~DispatcherImplWeakPtr(); | |
| 24 DispatcherImpl* get() { return m_dispatcher; } | |
| 25 void dispose() { m_dispatcher = nullptr; } | |
| 26 private: | |
| 27 DispatcherImpl* m_dispatcher; | |
| 28 }; | |
| 29 | |
| 30 class DispatcherImpl : public Dispatcher { | |
| 31 public: | |
| 32 DispatcherImpl(FrontendChannel* frontendChannel) | |
| 33 : m_frontendChannel(frontendChannel) | |
| 34 {% for domain in api.domains %} | |
| 35 , m_{{domain.domain | lower}}Agent(0) | |
| 36 {% endfor %} | |
| 37 { | |
| 38 {% for domain in api.domains %} | |
| 39 {% for command in domain.commands %} | |
| 40 {% if "redirect" in command %}{% continue %}{% endif %} | |
| 41 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{%
continue %}{% endif %} | |
| 42 m_dispatchMap.set("{{domain.domain}}.{{command.name}}", &DispatcherImpl:
:{{domain.domain}}_{{command.name}}); | |
| 43 {% endfor %} | |
| 44 {% endfor %} | |
| 45 | |
| 46 // Initialize common errors. | |
| 47 m_commonErrors.resize(LastEntry); | |
| 48 m_commonErrors[ParseError] = -32700; | |
| 49 m_commonErrors[InvalidRequest] = -32600; | |
| 50 m_commonErrors[MethodNotFound] = -32601; | |
| 51 m_commonErrors[InvalidParams] = -32602; | |
| 52 m_commonErrors[InternalError] = -32603; | |
| 53 m_commonErrors[ServerError] = -32000; | |
| 54 } | |
| 55 | |
| 56 ~DispatcherImpl() { clearFrontend(); } | |
| 57 | |
| 58 virtual void clearFrontend() | |
| 59 { | |
| 60 m_frontendChannel = nullptr; | |
| 61 for (auto& weak : m_weakPtrs) | |
| 62 weak.first->dispose(); | |
| 63 m_weakPtrs.clear(); | |
| 64 } | |
| 65 | |
| 66 std::unique_ptr<DispatcherImplWeakPtr> weakPtr() | |
| 67 { | |
| 68 std::unique_ptr<DispatcherImplWeakPtr> weak(new DispatcherImplWeakPtr(th
is)); | |
| 69 m_weakPtrs.add(weak.get()); | |
| 70 return weak; | |
| 71 } | |
| 72 | |
| 73 virtual void dispatch(const String16& message); | |
| 74 virtual void reportProtocolError(int callId, CommonErrorCode, const String16
& errorMessage, ErrorSupport* errors) const; | |
| 75 using Dispatcher::reportProtocolError; | |
| 76 | |
| 77 void sendResponse(int callId, const ErrorString& invocationError, ErrorSuppo
rt* errors, std::unique_ptr<protocol::DictionaryValue> result); | |
| 78 | |
| 79 {% for domain in api.domains %} | |
| 80 virtual void registerAgent(blink::protocol::{{domain.domain}}::Backend* agen
t) { DCHECK(!m_{{domain.domain | lower}}Agent); m_{{domain.domain | lower}}Agent
= agent; } | |
| 81 {% endfor %} | |
| 82 | |
| 83 private: | |
| 84 friend class DispatcherCallbackBase; | |
| 85 friend class DispatcherImplWeakPtr; | |
| 86 using CallHandler = void (DispatcherImpl::*)(int callId, std::unique_ptr<Dic
tionaryValue> messageObject, ErrorSupport* errors); | |
| 87 using DispatchMap = protocol::HashMap<String16, CallHandler>; | |
| 88 | |
| 89 {% for domain in api.domains %} | |
| 90 {% for command in domain.commands %} | |
| 91 {% if "redirect" in command %}{% continue %}{% endif %} | |
| 92 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{%
continue %}{% endif %} | |
| 93 void {{domain.domain}}_{{command.name}}(int callId, std::unique_ptr<Dictiona
ryValue> requestMessageObject, ErrorSupport*); | |
| 94 {% endfor %} | |
| 95 {% endfor %} | |
| 96 | |
| 97 FrontendChannel* m_frontendChannel; | |
| 98 | |
| 99 {% for domain in api.domains %} | |
| 100 {{domain.domain}}::Backend* m_{{domain.domain | lower}}Agent; | |
| 101 {% endfor %} | |
| 102 | |
| 103 void sendResponse(int callId, ErrorString invocationError, std::unique_ptr<p
rotocol::DictionaryValue> result) | |
| 104 { | |
| 105 sendResponse(callId, invocationError, nullptr, std::move(result)); | |
| 106 } | |
| 107 | |
| 108 void sendResponse(int callId, ErrorString invocationError) | |
| 109 { | |
| 110 sendResponse(callId, invocationError, nullptr, DictionaryValue::create()
); | |
| 111 } | |
| 112 | |
| 113 static const char kInvalidRequest[]; | |
| 114 | |
| 115 DispatchMap m_dispatchMap; | |
| 116 protocol::Vector<int> m_commonErrors; | |
| 117 protocol::HashSet<DispatcherImplWeakPtr*> m_weakPtrs; | |
| 118 }; | |
| 119 | |
| 120 class PLATFORM_EXPORT DispatcherCallbackBase : public protocol::BackendCallback
{ | |
| 121 public: | |
| 122 DispatcherCallbackBase(std::unique_ptr<DispatcherImplWeakPtr> backendImpl, i
nt callId) | |
| 123 : m_backendImpl(std::move(backendImpl)), m_callId(callId) { } | |
| 124 virtual ~DispatcherCallbackBase() { } | |
| 125 void dispose() { m_backendImpl = nullptr; } | |
| 126 | |
| 127 protected: | |
| 128 void sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage,
const ErrorString& invocationError) | |
| 129 { | |
| 130 if (!m_backendImpl->get()) | |
| 131 return; | |
| 132 m_backendImpl->get()->sendResponse(m_callId, invocationError, nullptr, s
td::move(partialMessage)); | |
| 133 m_backendImpl = nullptr; | |
| 134 } | |
| 135 | |
| 136 private: | |
| 137 std::unique_ptr<DispatcherImplWeakPtr> m_backendImpl; | |
| 138 int m_callId; | |
| 139 }; | |
| 140 | |
| 141 DispatcherImplWeakPtr::~DispatcherImplWeakPtr() | |
| 142 { | |
| 143 if (m_dispatcher) | |
| 144 m_dispatcher->m_weakPtrs.remove(this); | |
| 145 } | |
| 146 | |
| 147 const char DispatcherImpl::kInvalidRequest[] = "Invalid request"; | |
| 148 | |
| 149 {% for domain in api.domains %} | |
| 150 {% for command in domain.commands %} | |
| 151 {% if "redirect" in command %}{% continue %}{% endif %} | |
| 152 {% if "handlers" in command and not ("renderer" in command["handlers"]) %}{%
continue %}{% endif %} | |
| 153 | |
| 154 {% if "async" in command %} | |
| 155 | |
| 156 class PLATFORM_EXPORT {{domain.domain}}{{command.name | to_title_case}}Callback
: public {{domain.domain}}::Backend::{{command.name | to_title_case}}Callback, p
ublic DispatcherCallbackBase { | |
| 157 public: | |
| 158 {{domain.domain}}{{command.name | to_title_case}}Callback(std::unique_ptr<Di
spatcherImplWeakPtr> backendImpl, int callId) | |
| 159 : DispatcherCallbackBase(std::move(backendImpl), callId) { } | |
| 160 | |
| 161 void sendSuccess( | |
| 162 {%- for parameter in command.returns -%} | |
| 163 {%- if "optional" in parameter -%} | |
| 164 const Maybe<{{resolve_type(parameter).raw_type}}>& {{parameter.name}} | |
| 165 {%- else -%} | |
| 166 {{resolve_type(parameter).pass_type}} {{parameter.name}} | |
| 167 {%- endif -%} | |
| 168 {%- if not loop.last -%}, {% endif -%} | |
| 169 {%- endfor -%}) override | |
| 170 { | |
| 171 std::unique_ptr<protocol::DictionaryValue> resultObject = DictionaryValu
e::create(); | |
| 172 {% for parameter in command.returns %} | |
| 173 {% if "optional" in parameter %} | |
| 174 if ({{parameter.name}}.isJust()) | |
| 175 resultObject->setValue("{{parameter.name}}", toValue({{parameter.nam
e}}.fromJust())); | |
| 176 {% else %} | |
| 177 resultObject->setValue("{{parameter.name}}", toValue({{resolve_type(para
meter).to_raw_type % parameter.name}})); | |
| 178 {% endif %} | |
| 179 {% endfor %} | |
| 180 sendIfActive(std::move(resultObject), ErrorString()); | |
| 181 } | |
| 182 | |
| 183 void sendFailure(const ErrorString& error) override | |
| 184 { | |
| 185 DCHECK(error.length()); | |
| 186 sendIfActive(nullptr, error); | |
| 187 } | |
| 188 }; | |
| 189 {% endif %} | |
| 190 | |
| 191 void DispatcherImpl::{{domain.domain}}_{{command.name}}(int callId, std::unique_
ptr<DictionaryValue> requestMessageObject, ErrorSupport* errors) | |
| 192 { | |
| 193 if (!m_{{domain.domain | lower}}Agent) | |
| 194 errors->addError("{{domain.domain}} handler is not available."); | |
| 195 | |
| 196 if (errors->hasErrors()) { | |
| 197 reportProtocolError(callId, InvalidParams, kInvalidRequest, errors); | |
| 198 return; | |
| 199 } | |
| 200 {% if "parameters" in command %} | |
| 201 | |
| 202 // Prepare input parameters. | |
| 203 protocol::DictionaryValue* object = DictionaryValue::cast(requestMessageObje
ct->get("params")); | |
| 204 errors->push(); | |
| 205 {% for property in command.parameters %} | |
| 206 protocol::Value* {{property.name}}Value = object ? object->get("{{property.n
ame}}") : nullptr; | |
| 207 {% if property.optional %} | |
| 208 Maybe<{{resolve_type(property).raw_type}}> in_{{property.name}}; | |
| 209 if ({{property.name}}Value) { | |
| 210 errors->setName("{{property.name}}"); | |
| 211 in_{{property.name}} = FromValue<{{resolve_type(property).raw_type}}>::p
arse({{property.name}}Value, errors); | |
| 212 } | |
| 213 {% else %} | |
| 214 errors->setName("{{property.name}}"); | |
| 215 {{resolve_type(property).type}} in_{{property.name}} = FromValue<{{resolve_t
ype(property).raw_type}}>::parse({{property.name}}Value, errors); | |
| 216 {% endif %} | |
| 217 {% endfor %} | |
| 218 errors->pop(); | |
| 219 if (errors->hasErrors()) { | |
| 220 reportProtocolError(callId, InvalidParams, kInvalidRequest, errors); | |
| 221 return; | |
| 222 } | |
| 223 {% endif %} | |
| 224 | |
| 225 {% if "async" in command %} | |
| 226 std::unique_ptr<{{domain.domain}}{{command.name | to_title_case}}Callback> c
allback(new {{domain.domain}}{{command.name | to_title_case}}Callback(weakPtr(),
callId)); | |
| 227 {% elif "returns" in command %} | |
| 228 // Declare output parameters. | |
| 229 std::unique_ptr<protocol::DictionaryValue> result = DictionaryValue::create(
); | |
| 230 {% for property in command.returns %} | |
| 231 {% if "optional" in property %} | |
| 232 Maybe<{{resolve_type(property).raw_type}}> out_{{property.name}}; | |
| 233 {% else %} | |
| 234 {{resolve_type(property).type}} out_{{property.name}}; | |
| 235 {% endif %} | |
| 236 {% endfor %} | |
| 237 {% endif %} | |
| 238 | |
| 239 std::unique_ptr<DispatcherImplWeakPtr> weak = weakPtr(); | |
| 240 ErrorString error; | |
| 241 m_{{domain.domain | lower}}Agent->{{command.name}}(&error | |
| 242 {%- for property in command.parameters -%} | |
| 243 {%- if "optional" in property -%} | |
| 244 , in_{{property.name}} | |
| 245 {%- else -%} | |
| 246 , {{resolve_type(property).to_pass_type % ("in_" + property.name)}} | |
| 247 {%- endif -%} | |
| 248 {%- endfor %} | |
| 249 {%- if "async" in command -%} | |
| 250 , std::move(callback) | |
| 251 {%- elif "returns" in command %} | |
| 252 {%- for property in command.returns -%} | |
| 253 , &out_{{property.name}} | |
| 254 {%- endfor %} | |
| 255 {% endif %}); | |
| 256 {% if "returns" in command and not("async" in command) %} | |
| 257 if (!error.length()) { | |
| 258 {% for parameter in command.returns %} | |
| 259 {% if "optional" in parameter %} | |
| 260 if (out_{{parameter.name}}.isJust()) | |
| 261 result->setValue("{{parameter.name}}", toValue(out_{{parameter.name}
}.fromJust())); | |
| 262 {% else %} | |
| 263 result->setValue("{{parameter.name}}", toValue({{resolve_type(parameter)
.to_raw_type % ("out_" + parameter.name)}})); | |
| 264 {% endif %} | |
| 265 {% endfor %} | |
| 266 } | |
| 267 if (weak->get()) | |
| 268 weak->get()->sendResponse(callId, error, std::move(result)); | |
| 269 {% elif not("async" in command) %} | |
| 270 if (weak->get()) | |
| 271 weak->get()->sendResponse(callId, error); | |
| 272 {% endif %} | |
| 273 } | |
| 274 {% endfor %} | |
| 275 {% endfor %} | |
| 276 | |
| 277 std::unique_ptr<Dispatcher> Dispatcher::create(FrontendChannel* frontendChannel) | |
| 278 { | |
| 279 return wrapUnique(new DispatcherImpl(frontendChannel)); | |
| 280 } | |
| 281 | |
| 282 void DispatcherImpl::dispatch(const String16& message) | |
| 283 { | |
| 284 int callId = 0; | |
| 285 std::unique_ptr<protocol::Value> parsedMessage = parseJSON(message); | |
| 286 DCHECK(parsedMessage); | |
| 287 std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::
cast(std::move(parsedMessage)); | |
| 288 DCHECK(messageObject); | |
| 289 | |
| 290 protocol::Value* callIdValue = messageObject->get("id"); | |
| 291 bool success = callIdValue->asNumber(&callId); | |
| 292 DCHECK(success); | |
| 293 | |
| 294 protocol::Value* methodValue = messageObject->get("method"); | |
| 295 String16 method; | |
| 296 success = methodValue && methodValue->asString(&method); | |
| 297 DCHECK(success); | |
| 298 | |
| 299 protocol::HashMap<String16, CallHandler>::iterator it = m_dispatchMap.find(m
ethod); | |
| 300 if (it == m_dispatchMap.end()) { | |
| 301 reportProtocolError(callId, MethodNotFound, "'" + method + "' wasn't fou
nd"); | |
| 302 return; | |
| 303 } | |
| 304 | |
| 305 protocol::ErrorSupport errors; | |
| 306 ((*this).*(*it->second))(callId, std::move(messageObject), &errors); | |
| 307 } | |
| 308 | |
| 309 void DispatcherImpl::sendResponse(int callId, const ErrorString& invocationError
, ErrorSupport* errors, std::unique_ptr<protocol::DictionaryValue> result) | |
| 310 { | |
| 311 if (invocationError.length() || (errors && errors->hasErrors())) { | |
| 312 reportProtocolError(callId, ServerError, invocationError, errors); | |
| 313 return; | |
| 314 } | |
| 315 | |
| 316 std::unique_ptr<protocol::DictionaryValue> responseMessage = DictionaryValue
::create(); | |
| 317 responseMessage->setNumber("id", callId); | |
| 318 responseMessage->setObject("result", std::move(result)); | |
| 319 if (m_frontendChannel) | |
| 320 m_frontendChannel->sendProtocolResponse(callId, responseMessage->toJSONS
tring()); | |
| 321 } | |
| 322 | |
| 323 void Dispatcher::reportProtocolError(int callId, CommonErrorCode code, const Str
ing16& errorMessage) const | |
| 324 { | |
| 325 ErrorSupport errors; | |
| 326 reportProtocolError(callId, code, errorMessage, &errors); | |
| 327 } | |
| 328 | |
| 329 void DispatcherImpl::reportProtocolError(int callId, CommonErrorCode code, const
String16& errorMessage, ErrorSupport* errors) const | |
| 330 { | |
| 331 DCHECK(code >=0); | |
| 332 DCHECK((unsigned)code < m_commonErrors.size()); | |
| 333 DCHECK(m_commonErrors[code]); | |
| 334 std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create()
; | |
| 335 error->setNumber("code", m_commonErrors[code]); | |
| 336 error->setString("message", errorMessage); | |
| 337 DCHECK(error); | |
| 338 if (errors && errors->hasErrors()) | |
| 339 error->setString("data", errors->errors()); | |
| 340 std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create
(); | |
| 341 message->setObject("error", std::move(error)); | |
| 342 message->setNumber("id", callId); | |
| 343 if (m_frontendChannel) | |
| 344 m_frontendChannel->sendProtocolResponse(callId, message->toJSONString())
; | |
| 345 } | |
| 346 | |
| 347 bool Dispatcher::getCommandName(const String16& message, String16* result) | |
| 348 { | |
| 349 std::unique_ptr<protocol::Value> value = parseJSON(message); | |
| 350 if (!value) | |
| 351 return false; | |
| 352 | |
| 353 protocol::DictionaryValue* object = DictionaryValue::cast(value.get()); | |
| 354 if (!object) | |
| 355 return false; | |
| 356 | |
| 357 if (!object->getString("method", result)) | |
| 358 return false; | |
| 359 | |
| 360 return true; | |
| 361 } | |
| 362 | |
| 363 } // namespace protocol | |
| 364 } // namespace blink | |
| OLD | NEW |