[refactor] More post-NSS WebCrypto cleanups (utility functions).
[chromium-blink-merge.git] / content / browser / devtools / devtools_protocol_handler.cc
blob86ccd8e5d2d05830c5a9ada8be073fbf4f68104b
1 // Copyright 2014 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_handler.h"
7 #include "base/bind.h"
8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h"
10 #include "content/browser/devtools/devtools_manager.h"
11 #include "content/public/browser/devtools_manager_delegate.h"
13 namespace content {
15 namespace {
17 const char kIdParam[] = "id";
18 const char kMethodParam[] = "method";
19 const char kParamsParam[] = "params";
21 // JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object
22 const int kStatusParseError = -32700;
23 const int kStatusInvalidRequest = -32600;
24 const int kStatusNoSuchMethod = -32601;
26 scoped_ptr<base::DictionaryValue> TakeDictionary(base::DictionaryValue* dict,
27 const std::string& key) {
28 scoped_ptr<base::Value> value;
29 dict->Remove(key, &value);
30 base::DictionaryValue* result = nullptr;
31 if (value)
32 value.release()->GetAsDictionary(&result);
33 return make_scoped_ptr(result);
36 } // namespace
38 DevToolsProtocolHandler::DevToolsProtocolHandler(
39 DevToolsAgentHost* agent_host, const Notifier& notifier)
40 : agent_host_(agent_host),
41 client_(notifier),
42 dispatcher_(notifier) {
45 DevToolsProtocolHandler::~DevToolsProtocolHandler() {
48 void DevToolsProtocolHandler::HandleMessage(const std::string& message) {
49 scoped_ptr<base::DictionaryValue> command = ParseCommand(message);
50 if (!command)
51 return;
52 if (PassCommandToDelegate(command.get()))
53 return;
54 HandleCommand(command.Pass());
57 bool DevToolsProtocolHandler::HandleOptionalMessage(
58 const std::string& message, int* call_id) {
59 scoped_ptr<base::DictionaryValue> command = ParseCommand(message);
60 if (!command)
61 return true;
62 if (PassCommandToDelegate(command.get()))
63 return true;
64 return HandleOptionalCommand(command.Pass(), call_id);
67 bool DevToolsProtocolHandler::PassCommandToDelegate(
68 base::DictionaryValue* command) {
69 DevToolsManagerDelegate* delegate =
70 DevToolsManager::GetInstance()->delegate();
71 if (!delegate)
72 return false;
74 scoped_ptr<base::DictionaryValue> response(
75 delegate->HandleCommand(agent_host_, command));
76 if (response) {
77 std::string json_response;
78 base::JSONWriter::Write(*response, &json_response);
79 client_.SendRawMessage(json_response);
80 return true;
83 return false;
86 scoped_ptr<base::DictionaryValue>
87 DevToolsProtocolHandler::ParseCommand(const std::string& message) {
88 scoped_ptr<base::Value> value = base::JSONReader::Read(message);
89 if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) {
90 client_.SendError(DevToolsProtocolClient::kNoId,
91 Response(kStatusParseError,
92 "Message must be in JSON format"));
93 return nullptr;
96 scoped_ptr<base::DictionaryValue> command =
97 make_scoped_ptr(static_cast<base::DictionaryValue*>(value.release()));
98 int id = DevToolsProtocolClient::kNoId;
99 bool ok = command->GetInteger(kIdParam, &id) && id >= 0;
100 if (!ok) {
101 client_.SendError(id, Response(kStatusInvalidRequest,
102 "The type of 'id' property must be number"));
103 return nullptr;
106 std::string method;
107 ok = command->GetString(kMethodParam, &method);
108 if (!ok) {
109 client_.SendError(id,
110 Response(kStatusInvalidRequest,
111 "The type of 'method' property must be string"));
112 return nullptr;
115 return command;
118 void DevToolsProtocolHandler::HandleCommand(
119 scoped_ptr<base::DictionaryValue> command) {
120 int id = DevToolsProtocolClient::kNoId;
121 std::string method;
122 command->GetInteger(kIdParam, &id);
123 command->GetString(kMethodParam, &method);
124 DevToolsProtocolDispatcher::CommandHandler command_handler(
125 dispatcher_.FindCommandHandler(method));
126 if (command_handler.is_null()) {
127 client_.SendError(id, Response(kStatusNoSuchMethod, "No such method"));
128 return;
131 bool result =
132 command_handler.Run(id, TakeDictionary(command.get(), kParamsParam));
133 DCHECK(result);
136 bool DevToolsProtocolHandler::HandleOptionalCommand(
137 scoped_ptr<base::DictionaryValue> command, int* call_id) {
138 *call_id = DevToolsProtocolClient::kNoId;
139 std::string method;
140 command->GetInteger(kIdParam, call_id);
141 command->GetString(kMethodParam, &method);
142 DevToolsProtocolDispatcher::CommandHandler command_handler(
143 dispatcher_.FindCommandHandler(method));
144 if (!command_handler.is_null()) {
145 return command_handler.Run(
146 *call_id, TakeDictionary(command.get(), kParamsParam));
148 return false;
151 } // namespace content