Index: headless/lib/browser/headless_devtools_client_impl.cc |
diff --git a/headless/lib/browser/headless_devtools_client_impl.cc b/headless/lib/browser/headless_devtools_client_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8ce845336da9241c4b8f15627b67140bc28dc6a7 |
--- /dev/null |
+++ b/headless/lib/browser/headless_devtools_client_impl.cc |
@@ -0,0 +1,308 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "headless/lib/browser/headless_devtools_client_impl.h" |
+ |
+#include <memory> |
+ |
+#include "base/json/json_reader.h" |
+#include "base/json/json_writer.h" |
+#include "base/memory/ptr_util.h" |
+#include "base/values.h" |
+#include "content/public/browser/devtools_agent_host.h" |
+ |
+namespace headless { |
+ |
+// static |
+std::unique_ptr<HeadlessDevToolsClient> HeadlessDevToolsClient::Create() { |
+ return base::WrapUnique(new HeadlessDevToolsClientImpl()); |
+} |
+ |
+// static |
+HeadlessDevToolsClientImpl* HeadlessDevToolsClientImpl::From( |
+ HeadlessDevToolsClient* client) { |
+ // This downcast is safe because there is only one implementation of |
+ // HeadlessDevToolsClient. |
+ return static_cast<HeadlessDevToolsClientImpl*>(client); |
+} |
+ |
+HeadlessDevToolsClientImpl::HeadlessDevToolsClientImpl() |
+ : agent_host_(nullptr), |
+ next_message_id_(0), |
+ accessibility_domain_(this), |
+ animation_domain_(this), |
+ application_cache_domain_(this), |
+ cache_storage_domain_(this), |
+ console_domain_(this), |
+ css_domain_(this), |
+ database_domain_(this), |
+ debugger_domain_(this), |
+ device_orientation_domain_(this), |
+ dom_debugger_domain_(this), |
+ dom_domain_(this), |
+ dom_storage_domain_(this), |
+ emulation_domain_(this), |
+ heap_profiler_domain_(this), |
+ indexeddb_domain_(this), |
+ input_domain_(this), |
+ inspector_domain_(this), |
+ io_domain_(this), |
+ layer_tree_domain_(this), |
+ memory_domain_(this), |
+ network_domain_(this), |
+ page_domain_(this), |
+ profiler_domain_(this), |
+ rendering_domain_(this), |
+ runtime_domain_(this), |
+ security_domain_(this), |
+ service_worker_domain_(this), |
+ tracing_domain_(this), |
+ worker_domain_(this) {} |
+ |
+HeadlessDevToolsClientImpl::~HeadlessDevToolsClientImpl() {} |
+ |
+void HeadlessDevToolsClientImpl::AttachToHost( |
+ content::DevToolsAgentHost* agent_host) { |
+ DCHECK(!agent_host_); |
+ agent_host_ = agent_host; |
+ agent_host_->AttachClient(this); |
+} |
+ |
+void HeadlessDevToolsClientImpl::DetachFromHost( |
+ content::DevToolsAgentHost* agent_host) { |
+ DCHECK_EQ(agent_host_, agent_host); |
+ agent_host_->DetachClient(); |
+ agent_host_ = nullptr; |
+ pending_messages_.clear(); |
+} |
+ |
+void HeadlessDevToolsClientImpl::DispatchProtocolMessage( |
+ content::DevToolsAgentHost* agent_host, |
+ const std::string& json_message) { |
+ DCHECK_EQ(agent_host_, agent_host); |
+ std::unique_ptr<base::Value> message = |
+ base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); |
+ base::DictionaryValue* message_dict; |
+ if (!message || !message->GetAsDictionary(&message_dict)) { |
+ NOTREACHED() << "Badly formed reply"; |
+ return; |
+ } |
+ int id = 0; |
+ DCHECK(message_dict->GetInteger("id", &id)); |
+ auto it = pending_messages_.find(id); |
+ if (it == pending_messages_.end()) { |
+ NOTREACHED() << "Unexpected reply"; |
+ return; |
+ } |
+ base::DictionaryValue* result_dict; |
+ if (message_dict->GetDictionary("result", &result_dict)) { |
+ it->second.callback_with_result.Run(*result_dict); |
+ } else { |
+ it->second.callback.Run(); |
+ } |
+ pending_messages_.erase(it); |
+} |
+ |
+void HeadlessDevToolsClientImpl::AgentHostClosed( |
+ content::DevToolsAgentHost* agent_host, |
+ bool replaced_with_another_client) { |
+ DCHECK_EQ(agent_host_, agent_host); |
+ agent_host = nullptr; |
+ pending_messages_.clear(); |
+} |
+ |
+accessibility::Domain* HeadlessDevToolsClientImpl::GetAccessibility() { |
+ return &accessibility_domain_; |
+} |
+ |
+animation::Domain* HeadlessDevToolsClientImpl::GetAnimation() { |
+ return &animation_domain_; |
+} |
+ |
+application_cache::Domain* HeadlessDevToolsClientImpl::GetApplicationCache() { |
+ return &application_cache_domain_; |
+} |
+ |
+cache_storage::Domain* HeadlessDevToolsClientImpl::GetCacheStorage() { |
+ return &cache_storage_domain_; |
+} |
+ |
+console::Domain* HeadlessDevToolsClientImpl::GetConsole() { |
+ return &console_domain_; |
+} |
+ |
+css::Domain* HeadlessDevToolsClientImpl::GetCSS() { |
+ return &css_domain_; |
+} |
+ |
+database::Domain* HeadlessDevToolsClientImpl::GetDatabase() { |
+ return &database_domain_; |
+} |
+ |
+debugger::Domain* HeadlessDevToolsClientImpl::GetDebugger() { |
+ return &debugger_domain_; |
+} |
+ |
+device_orientation::Domain* HeadlessDevToolsClientImpl::GetDeviceOrientation() { |
+ return &device_orientation_domain_; |
+} |
+ |
+dom_debugger::Domain* HeadlessDevToolsClientImpl::GetDOMDebugger() { |
+ return &dom_debugger_domain_; |
+} |
+ |
+dom::Domain* HeadlessDevToolsClientImpl::GetDOM() { |
+ return &dom_domain_; |
+} |
+ |
+dom_storage::Domain* HeadlessDevToolsClientImpl::GetDOMStorage() { |
+ return &dom_storage_domain_; |
+} |
+ |
+emulation::Domain* HeadlessDevToolsClientImpl::GetEmulation() { |
+ return &emulation_domain_; |
+} |
+ |
+heap_profiler::Domain* HeadlessDevToolsClientImpl::GetHeapProfiler() { |
+ return &heap_profiler_domain_; |
+} |
+ |
+indexeddb::Domain* HeadlessDevToolsClientImpl::GetIndexedDB() { |
+ return &indexeddb_domain_; |
+} |
+ |
+input::Domain* HeadlessDevToolsClientImpl::GetInput() { |
+ return &input_domain_; |
+} |
+ |
+inspector::Domain* HeadlessDevToolsClientImpl::GetInspector() { |
+ return &inspector_domain_; |
+} |
+ |
+io::Domain* HeadlessDevToolsClientImpl::GetIO() { |
+ return &io_domain_; |
+} |
+ |
+layer_tree::Domain* HeadlessDevToolsClientImpl::GetLayerTree() { |
+ return &layer_tree_domain_; |
+} |
+ |
+memory::Domain* HeadlessDevToolsClientImpl::GetMemory() { |
+ return &memory_domain_; |
+} |
+ |
+network::Domain* HeadlessDevToolsClientImpl::GetNetwork() { |
+ return &network_domain_; |
+} |
+ |
+page::Domain* HeadlessDevToolsClientImpl::GetPage() { |
+ return &page_domain_; |
+} |
+ |
+profiler::Domain* HeadlessDevToolsClientImpl::GetProfiler() { |
+ return &profiler_domain_; |
+} |
+ |
+rendering::Domain* HeadlessDevToolsClientImpl::GetRendering() { |
+ return &rendering_domain_; |
+} |
+ |
+runtime::Domain* HeadlessDevToolsClientImpl::GetRuntime() { |
+ return &runtime_domain_; |
+} |
+ |
+security::Domain* HeadlessDevToolsClientImpl::GetSecurity() { |
+ return &security_domain_; |
+} |
+ |
+service_worker::Domain* HeadlessDevToolsClientImpl::GetServiceWorker() { |
+ return &service_worker_domain_; |
+} |
+ |
+tracing::Domain* HeadlessDevToolsClientImpl::GetTracing() { |
+ return &tracing_domain_; |
+} |
+ |
+worker::Domain* HeadlessDevToolsClientImpl::GetWorker() { |
+ return &worker_domain_; |
+} |
+ |
+template <typename CallbackType> |
+void HeadlessDevToolsClientImpl::FinalizeAndSendMessage( |
+ base::DictionaryValue* message, |
+ CallbackType callback) { |
+ DCHECK(agent_host_); |
+ int id = next_message_id_++; |
+ message->SetInteger("id", id); |
+ std::string json_message; |
+ base::JSONWriter::Write(*message, &json_message); |
+ pending_messages_[id] = PendingMessage(callback); |
+ agent_host_->DispatchProtocolMessage(json_message); |
+} |
+ |
+template <typename CallbackType> |
+void HeadlessDevToolsClientImpl::SendMessageWithParams( |
+ const char* method, |
+ std::unique_ptr<base::Value> params, |
+ CallbackType callback) { |
+ base::DictionaryValue message; |
+ message.SetString("method", method); |
+ message.Set("params", std::move(params)); |
+ FinalizeAndSendMessage(&message, std::move(callback)); |
+} |
+ |
+template <typename CallbackType> |
+void HeadlessDevToolsClientImpl::SendMessageWithoutParams( |
+ const char* method, |
+ CallbackType callback) { |
+ base::DictionaryValue message; |
+ message.SetString("method", method); |
+ FinalizeAndSendMessage(&message, std::move(callback)); |
+} |
+ |
+void HeadlessDevToolsClientImpl::SendMessage( |
+ const char* method, |
+ std::unique_ptr<base::Value> params, |
+ base::Callback<void(const base::Value&)> callback) { |
+ SendMessageWithParams(method, std::move(params), std::move(callback)); |
+} |
+ |
+void HeadlessDevToolsClientImpl::SendMessage( |
+ const char* method, |
+ std::unique_ptr<base::Value> params, |
+ base::Callback<void()> callback) { |
+ SendMessageWithParams(method, std::move(params), std::move(callback)); |
+} |
+ |
+void HeadlessDevToolsClientImpl::SendMessage( |
+ const char* method, |
+ base::Callback<void(const base::Value&)> callback) { |
+ SendMessageWithoutParams(method, std::move(callback)); |
+} |
+ |
+void HeadlessDevToolsClientImpl::SendMessage(const char* method, |
+ base::Callback<void()> callback) { |
+ SendMessageWithoutParams(method, std::move(callback)); |
+} |
+ |
+HeadlessDevToolsClientImpl::PendingMessage::PendingMessage() {} |
+ |
+HeadlessDevToolsClientImpl::PendingMessage::PendingMessage( |
+ PendingMessage&& other) = default; |
+ |
+HeadlessDevToolsClientImpl::PendingMessage::PendingMessage( |
+ base::Callback<void()> callback) |
+ : callback(callback) {} |
+ |
+HeadlessDevToolsClientImpl::PendingMessage::PendingMessage( |
+ base::Callback<void(const base::Value&)> callback) |
+ : callback_with_result(callback) {} |
+ |
+HeadlessDevToolsClientImpl::PendingMessage::~PendingMessage() {} |
+ |
+HeadlessDevToolsClientImpl::PendingMessage& |
+HeadlessDevToolsClientImpl::PendingMessage::operator=(PendingMessage&& other) = |
+ default; |
+ |
+} // namespace headless |