1// Copyright (c) 2011 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. 4 5#include "chrome/browser/debugger/devtools_remote_service.h" 6 7#include <string> 8 9#include "base/json/json_reader.h" 10#include "base/json/json_writer.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/values.h" 13#include "chrome/browser/debugger/devtools_manager.h" 14#include "chrome/browser/debugger/devtools_protocol_handler.h" 15#include "chrome/browser/debugger/devtools_remote_message.h" 16#include "chrome/browser/debugger/inspectable_tab_proxy.h" 17#include "chrome/common/devtools_messages.h" 18#include "content/browser/tab_contents/navigation_controller.h" 19#include "content/browser/tab_contents/navigation_entry.h" 20 21const char DevToolsRemoteServiceCommand::kPing[] = "ping"; 22const char DevToolsRemoteServiceCommand::kVersion[] = "version"; 23const char DevToolsRemoteServiceCommand::kListTabs[] = "list_tabs"; 24 25const char DevToolsRemoteService::kToolName[] = "DevToolsService"; 26 27namespace { 28const char kCommandKey[] = "command"; 29const char kDataKey[] = "data"; 30const char kResultKey[] = "result"; 31} // namespace 32 33DevToolsRemoteService::DevToolsRemoteService(DevToolsProtocolHandler* delegate) 34 : delegate_(delegate) {} 35 36DevToolsRemoteService::~DevToolsRemoteService() {} 37 38void DevToolsRemoteService::HandleMessage( 39 const DevToolsRemoteMessage& message) { 40 scoped_ptr<Value> request(base::JSONReader::Read(message.content(), false)); 41 if (request.get() == NULL) { 42 // Bad JSON 43 NOTREACHED(); 44 return; 45 } 46 DictionaryValue* json; 47 if (request->IsType(Value::TYPE_DICTIONARY)) { 48 json = static_cast<DictionaryValue*>(request.get()); 49 if (!json->HasKey(kCommandKey)) { 50 NOTREACHED(); // Broken protocol - no "command" specified 51 return; 52 } 53 } else { 54 NOTREACHED(); // Broken protocol - not a JS object 55 return; 56 } 57 ProcessJson(json, message); 58} 59 60void DevToolsRemoteService::ProcessJson(DictionaryValue* json, 61 const DevToolsRemoteMessage& message) { 62 static const std::string kOkResponse = "ok"; // "Ping" response 63 static const std::string kVersion = "0.1"; // Current protocol version 64 std::string command; 65 DictionaryValue response; 66 67 json->GetString(kCommandKey, &command); 68 response.SetString(kCommandKey, command); 69 70 if (command == DevToolsRemoteServiceCommand::kPing) { 71 response.SetInteger(kResultKey, Result::kOk); 72 response.SetString(kDataKey, kOkResponse); 73 } else if (command == DevToolsRemoteServiceCommand::kVersion) { 74 response.SetInteger(kResultKey, Result::kOk); 75 response.SetString(kDataKey, kVersion); 76 } else if (command == DevToolsRemoteServiceCommand::kListTabs) { 77 ListValue* data = new ListValue(); 78 const InspectableTabProxy::ControllersMap& navcon_map = 79 delegate_->inspectable_tab_proxy()->controllers_map(); 80 for (InspectableTabProxy::ControllersMap::const_iterator it = 81 navcon_map.begin(), end = navcon_map.end(); it != end; ++it) { 82 NavigationEntry* entry = it->second->GetActiveEntry(); 83 if (entry == NULL) { 84 continue; 85 } 86 if (entry->url().is_valid()) { 87 ListValue* tab = new ListValue(); 88 tab->Append(Value::CreateIntegerValue( 89 static_cast<int32>(it->second->session_id().id()))); 90 tab->Append(Value::CreateStringValue(entry->url().spec())); 91 data->Append(tab); 92 } 93 } 94 response.SetInteger(kResultKey, Result::kOk); 95 response.Set(kDataKey, data); 96 } else { 97 // Unknown protocol command. 98 NOTREACHED(); 99 response.SetInteger(kResultKey, Result::kUnknownCommand); 100 } 101 std::string response_json; 102 base::JSONWriter::Write(&response, false, &response_json); 103 scoped_ptr<DevToolsRemoteMessage> response_message( 104 DevToolsRemoteMessageBuilder::instance().Create(message.tool(), 105 message.destination(), 106 response_json)); 107 delegate_->Send(*response_message.get()); 108} 109