Android media: VideoFrame should not store so many sync points.
[chromium-blink-merge.git] / content / browser / devtools / devtools_protocol.cc
blob5e127f1dcbabd30964eef7841eebc01e6d90c352
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/devtools/devtools_protocol.h"
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/strings/stringprintf.h"
11 namespace content {
13 namespace {
15 const char kIdParam[] = "id";
16 const char kMethodParam[] = "method";
17 const char kParamsParam[] = "params";
18 const char kResultParam[] = "result";
19 const char kErrorParam[] = "error";
20 const char kErrorCodeParam[] = "code";
21 const char kErrorMessageParam[] = "message";
22 const int kNoId = -1;
24 // JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object
25 enum Error {
26 kErrorParseError = -32700,
27 kErrorInvalidRequest = -32600,
28 kErrorNoSuchMethod = -32601,
29 kErrorInvalidParams = -32602,
30 kErrorInternalError = -32603,
31 kErrorServerError = -32000
34 } // namespace
36 using base::Value;
38 DevToolsProtocol::Message::~Message() {
41 DevToolsProtocol::Message::Message(const std::string& method,
42 base::DictionaryValue* params)
43 : method_(method),
44 params_(params) {
45 size_t pos = method.find(".");
46 if (pos != std::string::npos && pos > 0)
47 domain_ = method.substr(0, pos);
50 DevToolsProtocol::Command::~Command() {
53 std::string DevToolsProtocol::Command::Serialize() {
54 base::DictionaryValue command;
55 command.SetInteger(kIdParam, id_);
56 command.SetString(kMethodParam, method_);
57 if (params_)
58 command.Set(kParamsParam, params_->DeepCopy());
60 std::string json_command;
61 base::JSONWriter::Write(&command, &json_command);
62 return json_command;
65 scoped_refptr<DevToolsProtocol::Response>
66 DevToolsProtocol::Command::SuccessResponse(base::DictionaryValue* result) {
67 return new DevToolsProtocol::Response(id_, result);
70 scoped_refptr<DevToolsProtocol::Response>
71 DevToolsProtocol::Command::InternalErrorResponse(const std::string& message) {
72 return new DevToolsProtocol::Response(id_, kErrorInternalError, message);
75 scoped_refptr<DevToolsProtocol::Response>
76 DevToolsProtocol::Command::InvalidParamResponse(const std::string& param) {
77 std::string message =
78 base::StringPrintf("Missing or invalid '%s' parameter", param.c_str());
79 return new DevToolsProtocol::Response(id_, kErrorInvalidParams, message);
82 scoped_refptr<DevToolsProtocol::Response>
83 DevToolsProtocol::Command::NoSuchMethodErrorResponse() {
84 return new Response(id_, kErrorNoSuchMethod, "No such method");
87 scoped_refptr<DevToolsProtocol::Response>
88 DevToolsProtocol::Command::ServerErrorResponse(const std::string& message) {
89 return new Response(id_, kErrorServerError, message);
92 scoped_refptr<DevToolsProtocol::Response>
93 DevToolsProtocol::Command::AsyncResponsePromise() {
94 scoped_refptr<DevToolsProtocol::Response> promise =
95 new DevToolsProtocol::Response(0, NULL);
96 promise->is_async_promise_ = true;
97 return promise;
100 DevToolsProtocol::Command::Command(int id,
101 const std::string& method,
102 base::DictionaryValue* params)
103 : Message(method, params),
104 id_(id) {
107 DevToolsProtocol::Response::~Response() {
110 std::string DevToolsProtocol::Response::Serialize() {
111 base::DictionaryValue response;
113 if (id_ != kNoId)
114 response.SetInteger(kIdParam, id_);
116 if (error_code_) {
117 base::DictionaryValue* error_object = new base::DictionaryValue();
118 response.Set(kErrorParam, error_object);
119 error_object->SetInteger(kErrorCodeParam, error_code_);
120 if (!error_message_.empty())
121 error_object->SetString(kErrorMessageParam, error_message_);
122 } else if (result_) {
123 response.Set(kResultParam, result_->DeepCopy());
126 std::string json_response;
127 base::JSONWriter::Write(&response, &json_response);
128 return json_response;
131 DevToolsProtocol::Response::Response(int id, base::DictionaryValue* result)
132 : id_(id),
133 result_(result),
134 error_code_(0),
135 is_async_promise_(false) {
138 DevToolsProtocol::Response::Response(int id,
139 int error_code,
140 const std::string& error_message)
141 : id_(id),
142 error_code_(error_code),
143 error_message_(error_message),
144 is_async_promise_(false) {
147 DevToolsProtocol::Notification::Notification(const std::string& method,
148 base::DictionaryValue* params)
149 : Message(method, params) {
152 DevToolsProtocol::Notification::~Notification() {
155 std::string DevToolsProtocol::Notification::Serialize() {
156 base::DictionaryValue notification;
157 notification.SetString(kMethodParam, method_);
158 if (params_)
159 notification.Set(kParamsParam, params_->DeepCopy());
161 std::string json_notification;
162 base::JSONWriter::Write(&notification, &json_notification);
163 return json_notification;
166 DevToolsProtocol::Handler::~Handler() {
169 scoped_refptr<DevToolsProtocol::Response>
170 DevToolsProtocol::Handler::HandleCommand(
171 scoped_refptr<DevToolsProtocol::Command> command) {
172 CommandHandlers::iterator it = command_handlers_.find(command->method());
173 if (it == command_handlers_.end())
174 return NULL;
175 return (it->second).Run(command);
178 void DevToolsProtocol::Handler::SetNotifier(const Notifier& notifier) {
179 notifier_ = notifier;
182 DevToolsProtocol::Handler::Handler() {
185 void DevToolsProtocol::Handler::RegisterCommandHandler(
186 const std::string& command,
187 const CommandHandler& handler) {
188 command_handlers_[command] = handler;
191 void DevToolsProtocol::Handler::SendNotification(
192 const std::string& method,
193 base::DictionaryValue* params) {
194 scoped_refptr<DevToolsProtocol::Notification> notification =
195 new DevToolsProtocol::Notification(method, params);
196 SendRawMessage(notification->Serialize());
199 void DevToolsProtocol::Handler::SendAsyncResponse(
200 scoped_refptr<DevToolsProtocol::Response> response) {
201 SendRawMessage(response->Serialize());
204 void DevToolsProtocol::Handler::SendRawMessage(const std::string& message) {
205 if (!notifier_.is_null())
206 notifier_.Run(message);
209 static bool ParseMethod(base::DictionaryValue* command,
210 std::string* method) {
211 if (!command->GetString(kMethodParam, method))
212 return false;
213 size_t pos = method->find(".");
214 if (pos == std::string::npos || pos == 0)
215 return false;
216 return true;
219 // static
220 scoped_refptr<DevToolsProtocol::Command> DevToolsProtocol::ParseCommand(
221 const std::string& json,
222 std::string* error_response) {
223 scoped_ptr<base::DictionaryValue> command_dict(
224 ParseMessage(json, error_response));
225 return ParseCommand(command_dict.get(), error_response);
228 // static
229 scoped_refptr<DevToolsProtocol::Command> DevToolsProtocol::ParseCommand(
230 base::DictionaryValue* command_dict,
231 std::string* error_response) {
232 if (!command_dict)
233 return NULL;
235 int id;
236 std::string method;
237 bool ok = command_dict->GetInteger(kIdParam, &id) && id >= 0;
238 ok = ok && ParseMethod(command_dict, &method);
239 if (!ok) {
240 scoped_refptr<Response> response =
241 new Response(kNoId, kErrorInvalidRequest, "No such method");
242 *error_response = response->Serialize();
243 return NULL;
246 base::DictionaryValue* params = NULL;
247 command_dict->GetDictionary(kParamsParam, &params);
248 return new Command(id, method, params ? params->DeepCopy() : NULL);
251 // static
252 scoped_refptr<DevToolsProtocol::Command>
253 DevToolsProtocol::CreateCommand(
254 int id,
255 const std::string& method,
256 base::DictionaryValue* params) {
257 return new Command(id, method, params);
260 //static
261 scoped_refptr<DevToolsProtocol::Response>
262 DevToolsProtocol::ParseResponse(
263 base::DictionaryValue* response_dict) {
264 int id;
265 if (!response_dict->GetInteger(kIdParam, &id))
266 id = kNoId;
268 const base::DictionaryValue* error_dict;
269 if (response_dict->GetDictionary(kErrorParam, &error_dict)) {
270 int error_code = kErrorInternalError;
271 response_dict->GetInteger(kErrorCodeParam, &error_code);
272 std::string error_message;
273 response_dict->GetString(kErrorMessageParam, &error_message);
274 return new Response(id, error_code, error_message);
277 const base::DictionaryValue* result = NULL;
278 response_dict->GetDictionary(kResultParam, &result);
279 return new Response(id, result ? result->DeepCopy() : NULL);
282 // static
283 scoped_refptr<DevToolsProtocol::Notification>
284 DevToolsProtocol::ParseNotification(const std::string& json) {
285 scoped_ptr<base::DictionaryValue> dict(ParseMessage(json, NULL));
286 if (!dict)
287 return NULL;
289 std::string method;
290 bool ok = ParseMethod(dict.get(), &method);
291 if (!ok)
292 return NULL;
294 base::DictionaryValue* params = NULL;
295 dict->GetDictionary(kParamsParam, &params);
296 return new Notification(method, params ? params->DeepCopy() : NULL);
299 //static
300 scoped_refptr<DevToolsProtocol::Notification>
301 DevToolsProtocol::CreateNotification(
302 const std::string& method,
303 base::DictionaryValue* params) {
304 return new Notification(method, params);
307 // static
308 base::DictionaryValue* DevToolsProtocol::ParseMessage(
309 const std::string& json,
310 std::string* error_response) {
311 int parse_error_code;
312 std::string error_message;
313 scoped_ptr<base::Value> message(
314 base::JSONReader::ReadAndReturnError(
315 json, 0, &parse_error_code, &error_message));
317 if (!message || !message->IsType(base::Value::TYPE_DICTIONARY)) {
318 scoped_refptr<Response> response =
319 new Response(0, kErrorParseError, error_message);
320 if (error_response)
321 *error_response = response->Serialize();
322 return NULL;
325 return static_cast<base::DictionaryValue*>(message.release());
328 } // namespace content