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 21 const char DevToolsRemoteServiceCommand::kPing[] = "ping"; 22 const char DevToolsRemoteServiceCommand::kVersion[] = "version"; 23 const char DevToolsRemoteServiceCommand::kListTabs[] = "list_tabs"; 24 25 const char DevToolsRemoteService::kToolName[] = "DevToolsService"; 26 27 namespace { 28 const char kCommandKey[] = "command"; 29 const char kDataKey[] = "data"; 30 const char kResultKey[] = "result"; 31 } // namespace 32 33 DevToolsRemoteService::DevToolsRemoteService(DevToolsProtocolHandler* delegate) 34 : delegate_(delegate) {} 35 36 DevToolsRemoteService::~DevToolsRemoteService() {} 37 38 void 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 60 void 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