1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// found in the LICENSE file. 4bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/devtools/devtools_protocol.h" 6bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 7bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/json/json_reader.h" 8bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/json/json_writer.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/strings/stringprintf.h" 10bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 11bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace { 12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorCodeParam[] = "code"; 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorParam[] = "error"; 15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kErrorMessageParam[] = "message"; 16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochconst char kIdParam[] = "id"; 17bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochconst char kMethodParam[] = "method"; 18bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochconst char kParamsParam[] = "params"; 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kResultParam[] = "result"; 20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// JSON RPC 2.0 spec: http://www.jsonrpc.org/specification#error_object 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)enum Error { 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kErrorInvalidParams = -32602 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 26bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} // namespace 27bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 28bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochDevToolsProtocol::Message::~Message() { 29bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 30bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 31bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochDevToolsProtocol::Message::Message(const std::string& method, 32bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::DictionaryValue* params) 33bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch : method_(method), 34bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch params_(params ? params->DeepCopy() : NULL) { 35bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 36bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 37bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochDevToolsProtocol::Command::Command(int id, 38bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch const std::string& method, 39bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::DictionaryValue* params) 40bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch : Message(method, params), 41bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch id_(id) { 42bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 43bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 44bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochDevToolsProtocol::Command::~Command() { 45bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 46bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochstd::string DevToolsProtocol::Command::Serialize() { 48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::DictionaryValue command; 49bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch command.SetInteger(kIdParam, id_); 50bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch command.SetString(kMethodParam, method_); 51bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (params_) 52bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch command.Set(kParamsParam, params_->DeepCopy()); 53bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 54bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch std::string json_command; 55bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::JSONWriter::Write(&command, &json_command); 56bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return json_command; 57bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 58bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<DevToolsProtocol::Response> 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DevToolsProtocol::Command::SuccessResponse(base::DictionaryValue* result) { 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<DevToolsProtocol::Response>( 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new DevToolsProtocol::Response(id_, result)); 63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)scoped_ptr<DevToolsProtocol::Response> 66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DevToolsProtocol::Command::InvalidParamResponse(const std::string& param) { 67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string message = 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::StringPrintf("Missing or invalid '%s' parameter", param.c_str()); 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return scoped_ptr<DevToolsProtocol::Response>( 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new DevToolsProtocol::Response(id_, kErrorInvalidParams, message)); 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 73bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochDevToolsProtocol::Notification::~Notification() { 74bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 75bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 76bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochDevToolsProtocol::Notification::Notification(const std::string& method, 77bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::DictionaryValue* params) 78bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch : Message(method, params) { 79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 81c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben MurdochDevToolsProtocol::Response::~Response() { 82c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch} 83c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DevToolsProtocol::Response::Response(int id, 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int error_code, 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string error_message) 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : id_(id), 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_code_(error_code), 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_message_(error_message) { 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DevToolsProtocol::Response::Response(int id, base::DictionaryValue* result) 93c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch : id_(id), 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_code_(0), 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) result_(result) { 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)base::DictionaryValue* DevToolsProtocol::Response::Serialize() { 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue* response = new base::DictionaryValue(); 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) response->SetInteger(kIdParam, id_); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (error_code_) { 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue* error_object = new base::DictionaryValue(); 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) response->Set(kErrorParam, error_object); 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_object->SetInteger(kErrorCodeParam, error_code_); 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!error_message_.empty()) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_object->SetString(kErrorMessageParam, error_message_); 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (result_) 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) response->Set(kResultParam, result_->DeepCopy()); 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) response->Set(kResultParam, new base::DictionaryValue()); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 116cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return response; 117cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)DevToolsProtocol::Command* DevToolsProtocol::ParseCommand( 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue* command_dict) { 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!command_dict) 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return NULL; 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int id; 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!command_dict->GetInteger(kIdParam, &id) || id < 0) 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return NULL; 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string method; 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!command_dict->GetString(kMethodParam, &method)) 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return NULL; 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::DictionaryValue* params = NULL; 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) command_dict->GetDictionary(kParamsParam, ¶ms); 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new Command(id, method, params); 136c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch} 137c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 138bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// static 139bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochDevToolsProtocol::Notification* DevToolsProtocol::ParseNotification( 140bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch const std::string& json) { 141bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_ptr<base::Value> value(base::JSONReader::Read(json)); 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) 143bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return NULL; 144bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 145bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_ptr<base::DictionaryValue> dict( 146bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<base::DictionaryValue*>(value.release())); 147bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 148bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch std::string method; 149bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!dict->GetString(kMethodParam, &method)) 150bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return NULL; 151bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 152bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch base::DictionaryValue* params = NULL; 153bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch dict->GetDictionary(kParamsParam, ¶ms); 154bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return new Notification(method, params); 155bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 156c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 157c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben MurdochDevToolsProtocol::Response* DevToolsProtocol::ParseResponse( 158c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch const std::string& json) { 159c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch scoped_ptr<base::Value> value(base::JSONReader::Read(json)); 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!value || !value->IsType(base::Value::TYPE_DICTIONARY)) 161c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return NULL; 162c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 163c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch scoped_ptr<base::DictionaryValue> dict( 164c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch static_cast<base::DictionaryValue*>(value.release())); 165c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 166c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch int id; 167c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (!dict->GetInteger(kIdParam, &id)) 168c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch return NULL; 169c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch 170c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch int error_code = 0; 171c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch base::DictionaryValue* error_dict = NULL; 172c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch if (dict->GetDictionary(kErrorParam, &error_dict)) 173c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch error_dict->GetInteger(kErrorCodeParam, &error_code); 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new Response(id, error_code, std::string()); 175c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch} 176