| 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
|
|
|