Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 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 "headless/lib/browser/headless_devtools_client_impl.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 | |
| 9 #include "base/json/json_reader.h" | |
| 10 #include "base/json/json_writer.h" | |
| 11 #include "base/memory/ptr_util.h" | |
| 12 #include "base/values.h" | |
| 13 #include "content/public/browser/devtools_agent_host.h" | |
| 14 | |
| 15 namespace headless { | |
| 16 | |
| 17 // static | |
| 18 std::unique_ptr<HeadlessDevToolsClient> HeadlessDevToolsClient::Create() { | |
| 19 return base::WrapUnique(new HeadlessDevToolsClientImpl()); | |
| 20 } | |
| 21 | |
| 22 // static | |
| 23 HeadlessDevToolsClientImpl* HeadlessDevToolsClientImpl::From( | |
| 24 HeadlessDevToolsClient* client) { | |
| 25 // This downcast is safe because there is only one implementation of | |
| 26 // HeadlessDevToolsClient. | |
| 27 return static_cast<HeadlessDevToolsClientImpl*>(client); | |
| 28 } | |
| 29 | |
| 30 HeadlessDevToolsClientImpl::HeadlessDevToolsClientImpl() | |
| 31 : agent_host_(nullptr), | |
| 32 next_message_id_(0), | |
| 33 accessibility_domain_(this), | |
| 34 animation_domain_(this), | |
| 35 application_cache_domain_(this), | |
| 36 cache_storage_domain_(this), | |
| 37 console_domain_(this), | |
| 38 css_domain_(this), | |
| 39 database_domain_(this), | |
| 40 debugger_domain_(this), | |
| 41 device_orientation_domain_(this), | |
| 42 dom_debugger_domain_(this), | |
| 43 dom_domain_(this), | |
| 44 dom_storage_domain_(this), | |
| 45 emulation_domain_(this), | |
| 46 heap_profiler_domain_(this), | |
| 47 indexeddb_domain_(this), | |
| 48 input_domain_(this), | |
| 49 inspector_domain_(this), | |
| 50 io_domain_(this), | |
| 51 layer_tree_domain_(this), | |
| 52 memory_domain_(this), | |
| 53 network_domain_(this), | |
| 54 page_domain_(this), | |
| 55 profiler_domain_(this), | |
| 56 rendering_domain_(this), | |
| 57 runtime_domain_(this), | |
| 58 security_domain_(this), | |
| 59 service_worker_domain_(this), | |
| 60 tracing_domain_(this), | |
| 61 worker_domain_(this) {} | |
| 62 | |
| 63 HeadlessDevToolsClientImpl::~HeadlessDevToolsClientImpl() {} | |
| 64 | |
| 65 void HeadlessDevToolsClientImpl::AttachToHost( | |
| 66 content::DevToolsAgentHost* agent_host) { | |
| 67 DCHECK(!agent_host_); | |
| 68 agent_host_ = agent_host; | |
| 69 agent_host_->AttachClient(this); | |
| 70 } | |
| 71 | |
| 72 void HeadlessDevToolsClientImpl::DetachFromHost( | |
| 73 content::DevToolsAgentHost* agent_host) { | |
| 74 DCHECK_EQ(agent_host_, agent_host); | |
| 75 agent_host_->DetachClient(); | |
| 76 agent_host_ = nullptr; | |
| 77 pending_messages_.clear(); | |
| 78 } | |
| 79 | |
| 80 void HeadlessDevToolsClientImpl::DispatchProtocolMessage( | |
| 81 content::DevToolsAgentHost* agent_host, | |
| 82 const std::string& json_message) { | |
| 83 DCHECK_EQ(agent_host_, agent_host); | |
| 84 std::unique_ptr<base::Value> message = | |
| 85 base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); | |
| 86 base::DictionaryValue* message_dict; | |
| 87 if (!message || !message->GetAsDictionary(&message_dict)) { | |
| 88 NOTREACHED() << "Badly formed reply"; | |
| 89 return; | |
| 90 } | |
| 91 int id = 0; | |
| 92 DCHECK(message_dict->GetInteger("id", &id)); | |
| 93 auto it = pending_messages_.find(id); | |
| 94 if (it == pending_messages_.end()) { | |
| 95 NOTREACHED() << "Unexpected reply"; | |
| 96 return; | |
| 97 } | |
| 98 base::DictionaryValue* result_dict; | |
| 99 if (message_dict->GetDictionary("result", &result_dict)) { | |
| 100 it->second.callback_with_result.Run(*result_dict); | |
| 101 } else { | |
| 102 it->second.callback.Run(); | |
| 103 } | |
| 104 pending_messages_.erase(it); | |
| 105 } | |
| 106 | |
| 107 void HeadlessDevToolsClientImpl::AgentHostClosed( | |
| 108 content::DevToolsAgentHost* agent_host, | |
| 109 bool replaced_with_another_client) { | |
| 110 DCHECK_EQ(agent_host_, agent_host); | |
| 111 agent_host = nullptr; | |
| 112 pending_messages_.clear(); | |
| 113 } | |
| 114 | |
| 115 accessibility::Domain* HeadlessDevToolsClientImpl::GetAccessibility() { | |
| 116 return &accessibility_domain_; | |
| 117 } | |
| 118 | |
| 119 animation::Domain* HeadlessDevToolsClientImpl::GetAnimation() { | |
| 120 return &animation_domain_; | |
| 121 } | |
| 122 | |
| 123 application_cache::Domain* HeadlessDevToolsClientImpl::GetApplicationCache() { | |
| 124 return &application_cache_domain_; | |
| 125 } | |
| 126 | |
| 127 cache_storage::Domain* HeadlessDevToolsClientImpl::GetCacheStorage() { | |
| 128 return &cache_storage_domain_; | |
| 129 } | |
| 130 | |
| 131 console::Domain* HeadlessDevToolsClientImpl::GetConsole() { | |
| 132 return &console_domain_; | |
| 133 } | |
| 134 | |
| 135 css::Domain* HeadlessDevToolsClientImpl::GetCSS() { | |
| 136 return &css_domain_; | |
| 137 } | |
| 138 | |
| 139 database::Domain* HeadlessDevToolsClientImpl::GetDatabase() { | |
| 140 return &database_domain_; | |
| 141 } | |
| 142 | |
| 143 debugger::Domain* HeadlessDevToolsClientImpl::GetDebugger() { | |
| 144 return &debugger_domain_; | |
| 145 } | |
| 146 | |
| 147 device_orientation::Domain* HeadlessDevToolsClientImpl::GetDeviceOrientation() { | |
| 148 return &device_orientation_domain_; | |
| 149 } | |
| 150 | |
| 151 dom_debugger::Domain* HeadlessDevToolsClientImpl::GetDOMDebugger() { | |
| 152 return &dom_debugger_domain_; | |
| 153 } | |
| 154 | |
| 155 dom::Domain* HeadlessDevToolsClientImpl::GetDOM() { | |
| 156 return &dom_domain_; | |
| 157 } | |
| 158 | |
| 159 dom_storage::Domain* HeadlessDevToolsClientImpl::GetDOMStorage() { | |
| 160 return &dom_storage_domain_; | |
| 161 } | |
| 162 | |
| 163 emulation::Domain* HeadlessDevToolsClientImpl::GetEmulation() { | |
| 164 return &emulation_domain_; | |
| 165 } | |
| 166 | |
| 167 heap_profiler::Domain* HeadlessDevToolsClientImpl::GetHeapProfiler() { | |
| 168 return &heap_profiler_domain_; | |
| 169 } | |
| 170 | |
| 171 indexeddb::Domain* HeadlessDevToolsClientImpl::GetIndexedDB() { | |
| 172 return &indexeddb_domain_; | |
| 173 } | |
| 174 | |
| 175 input::Domain* HeadlessDevToolsClientImpl::GetInput() { | |
| 176 return &input_domain_; | |
| 177 } | |
| 178 | |
| 179 inspector::Domain* HeadlessDevToolsClientImpl::GetInspector() { | |
| 180 return &inspector_domain_; | |
| 181 } | |
| 182 | |
| 183 io::Domain* HeadlessDevToolsClientImpl::GetIO() { | |
| 184 return &io_domain_; | |
| 185 } | |
| 186 | |
| 187 layer_tree::Domain* HeadlessDevToolsClientImpl::GetLayerTree() { | |
| 188 return &layer_tree_domain_; | |
| 189 } | |
| 190 | |
| 191 memory::Domain* HeadlessDevToolsClientImpl::GetMemory() { | |
| 192 return &memory_domain_; | |
| 193 } | |
| 194 | |
| 195 network::Domain* HeadlessDevToolsClientImpl::GetNetwork() { | |
| 196 return &network_domain_; | |
| 197 } | |
| 198 | |
| 199 page::Domain* HeadlessDevToolsClientImpl::GetPage() { | |
| 200 return &page_domain_; | |
| 201 } | |
| 202 | |
| 203 profiler::Domain* HeadlessDevToolsClientImpl::GetProfiler() { | |
| 204 return &profiler_domain_; | |
| 205 } | |
| 206 | |
| 207 rendering::Domain* HeadlessDevToolsClientImpl::GetRendering() { | |
| 208 return &rendering_domain_; | |
| 209 } | |
| 210 | |
| 211 runtime::Domain* HeadlessDevToolsClientImpl::GetRuntime() { | |
| 212 return &runtime_domain_; | |
| 213 } | |
| 214 | |
| 215 security::Domain* HeadlessDevToolsClientImpl::GetSecurity() { | |
| 216 return &security_domain_; | |
| 217 } | |
| 218 | |
| 219 service_worker::Domain* HeadlessDevToolsClientImpl::GetServiceWorker() { | |
| 220 return &service_worker_domain_; | |
| 221 } | |
| 222 | |
| 223 tracing::Domain* HeadlessDevToolsClientImpl::GetTracing() { | |
| 224 return &tracing_domain_; | |
| 225 } | |
| 226 | |
| 227 worker::Domain* HeadlessDevToolsClientImpl::GetWorker() { | |
| 228 return &worker_domain_; | |
| 229 } | |
| 230 | |
| 231 void HeadlessDevToolsClientImpl::SendMessage( | |
| 232 const char* method, | |
| 233 std::unique_ptr<base::Value> params, | |
| 234 base::Callback<void(const base::Value&)> callback) { | |
| 235 base::DictionaryValue message; | |
| 236 message.SetString("method", method); | |
| 237 message.Set("params", std::move(params)); | |
| 238 int id = FinalizeAndSendMessage(&message); | |
| 239 pending_messages_[id] = PendingMessage(callback); | |
| 240 } | |
| 241 | |
| 242 void HeadlessDevToolsClientImpl::SendMessage( | |
| 243 const char* method, | |
| 244 std::unique_ptr<base::Value> params, | |
| 245 base::Callback<void()> callback) { | |
| 246 base::DictionaryValue message; | |
| 247 message.SetString("method", method); | |
| 248 message.Set("params", std::move(params)); | |
| 249 int id = FinalizeAndSendMessage(&message); | |
| 250 pending_messages_[id] = PendingMessage(callback); | |
| 251 } | |
| 252 | |
| 253 void HeadlessDevToolsClientImpl::SendMessage( | |
| 254 const char* method, | |
| 255 base::Callback<void(const base::Value&)> callback) { | |
| 256 base::DictionaryValue message; | |
| 257 message.SetString("method", method); | |
| 258 int id = FinalizeAndSendMessage(&message); | |
| 259 pending_messages_[id] = PendingMessage(callback); | |
| 260 } | |
| 261 | |
| 262 void HeadlessDevToolsClientImpl::SendMessage(const char* method, | |
|
altimin
2016/04/14 12:54:12
Looks like these three methods have a lot in commo
Sami
2016/04/15 14:43:44
Refactored.
| |
| 263 base::Callback<void()> callback) { | |
| 264 base::DictionaryValue message; | |
| 265 message.SetString("method", method); | |
| 266 int id = FinalizeAndSendMessage(&message); | |
| 267 pending_messages_[id] = PendingMessage(callback); | |
| 268 } | |
| 269 | |
| 270 int HeadlessDevToolsClientImpl::FinalizeAndSendMessage( | |
| 271 base::DictionaryValue* message) { | |
| 272 DCHECK(agent_host_); | |
| 273 int id = next_message_id_++; | |
| 274 message->SetInteger("id", id); | |
| 275 std::string json_message; | |
| 276 base::JSONWriter::Write(*message, &json_message); | |
| 277 agent_host_->DispatchProtocolMessage(json_message); | |
|
dgozman
2016/04/14 18:01:54
This could synchronously call |DispatchProtocolMes
Sami
2016/04/15 14:43:44
Well spotted, thanks.
| |
| 278 return id; | |
| 279 } | |
| 280 | |
| 281 HeadlessDevToolsClientImpl::PendingMessage::PendingMessage() {} | |
| 282 | |
| 283 HeadlessDevToolsClientImpl::PendingMessage::PendingMessage( | |
| 284 base::Callback<void()> callback) | |
| 285 : callback(callback) {} | |
| 286 | |
| 287 HeadlessDevToolsClientImpl::PendingMessage::PendingMessage( | |
| 288 base::Callback<void(const base::Value&)> callback) | |
| 289 : callback_with_result(callback) {} | |
| 290 | |
| 291 HeadlessDevToolsClientImpl::PendingMessage::~PendingMessage() {} | |
| 292 | |
| 293 } // namespace headless | |
| OLD | NEW |