| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "headless/lib/browser/headless_devtools_client_impl.h" | 5 #include "headless/lib/browser/headless_devtools_client_impl.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/bind.h" |
| 9 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 10 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
| 11 #include "base/memory/ptr_util.h" | 12 #include "base/memory/ptr_util.h" |
| 12 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "content/public/browser/browser_thread.h" |
| 13 #include "content/public/browser/devtools_agent_host.h" | 15 #include "content/public/browser/devtools_agent_host.h" |
| 14 | 16 |
| 15 namespace headless { | 17 namespace headless { |
| 16 | 18 |
| 17 // static | 19 // static |
| 18 std::unique_ptr<HeadlessDevToolsClient> HeadlessDevToolsClient::Create() { | 20 std::unique_ptr<HeadlessDevToolsClient> HeadlessDevToolsClient::Create() { |
| 19 return base::WrapUnique(new HeadlessDevToolsClientImpl()); | 21 return base::WrapUnique(new HeadlessDevToolsClientImpl()); |
| 20 } | 22 } |
| 21 | 23 |
| 22 // static | 24 // static |
| (...skipping 30 matching lines...) Expand all Loading... |
| 53 log_domain_(this), | 55 log_domain_(this), |
| 54 memory_domain_(this), | 56 memory_domain_(this), |
| 55 network_domain_(this), | 57 network_domain_(this), |
| 56 page_domain_(this), | 58 page_domain_(this), |
| 57 profiler_domain_(this), | 59 profiler_domain_(this), |
| 58 rendering_domain_(this), | 60 rendering_domain_(this), |
| 59 runtime_domain_(this), | 61 runtime_domain_(this), |
| 60 security_domain_(this), | 62 security_domain_(this), |
| 61 service_worker_domain_(this), | 63 service_worker_domain_(this), |
| 62 tracing_domain_(this), | 64 tracing_domain_(this), |
| 63 worker_domain_(this) {} | 65 worker_domain_(this), |
| 66 browser_main_thread_(content::BrowserThread::GetTaskRunnerForThread( |
| 67 content::BrowserThread::UI)), |
| 68 weak_ptr_factory_(this) {} |
| 64 | 69 |
| 65 HeadlessDevToolsClientImpl::~HeadlessDevToolsClientImpl() {} | 70 HeadlessDevToolsClientImpl::~HeadlessDevToolsClientImpl() {} |
| 66 | 71 |
| 67 void HeadlessDevToolsClientImpl::AttachToHost( | 72 void HeadlessDevToolsClientImpl::AttachToHost( |
| 68 content::DevToolsAgentHost* agent_host) { | 73 content::DevToolsAgentHost* agent_host) { |
| 69 DCHECK(!agent_host_); | 74 DCHECK(!agent_host_); |
| 70 agent_host_ = agent_host; | 75 agent_host_ = agent_host; |
| 71 agent_host_->AttachClient(this); | 76 agent_host_->AttachClient(this); |
| 72 } | 77 } |
| 73 | 78 |
| 74 void HeadlessDevToolsClientImpl::DetachFromHost( | 79 void HeadlessDevToolsClientImpl::DetachFromHost( |
| 75 content::DevToolsAgentHost* agent_host) { | 80 content::DevToolsAgentHost* agent_host) { |
| 76 DCHECK_EQ(agent_host_, agent_host); | 81 DCHECK_EQ(agent_host_, agent_host); |
| 77 agent_host_->DetachClient(this); | 82 agent_host_->DetachClient(this); |
| 78 agent_host_ = nullptr; | 83 agent_host_ = nullptr; |
| 79 pending_messages_.clear(); | 84 pending_messages_.clear(); |
| 80 } | 85 } |
| 81 | 86 |
| 82 void HeadlessDevToolsClientImpl::DispatchProtocolMessage( | 87 void HeadlessDevToolsClientImpl::DispatchProtocolMessage( |
| 83 content::DevToolsAgentHost* agent_host, | 88 content::DevToolsAgentHost* agent_host, |
| 84 const std::string& json_message) { | 89 const std::string& json_message) { |
| 85 DCHECK_EQ(agent_host_, agent_host); | 90 DCHECK_EQ(agent_host_, agent_host); |
| 86 std::unique_ptr<base::Value> message = | 91 std::unique_ptr<base::Value> message = |
| 87 base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); | 92 base::JSONReader::Read(json_message, base::JSON_PARSE_RFC); |
| 88 const base::DictionaryValue* message_dict; | 93 const base::DictionaryValue* message_dict; |
| 89 if (!message || !message->GetAsDictionary(&message_dict)) { | 94 if (!message || !message->GetAsDictionary(&message_dict)) { |
| 90 NOTREACHED() << "Badly formed reply"; | 95 NOTREACHED() << "Badly formed reply"; |
| 91 return; | 96 return; |
| 92 } | 97 } |
| 93 if (!DispatchMessageReply(*message_dict) && !DispatchEvent(*message_dict)) | 98 if (!DispatchMessageReply(*message_dict) && |
| 99 !DispatchEvent(std::move(message), *message_dict)) { |
| 94 DLOG(ERROR) << "Unhandled protocol message: " << json_message; | 100 DLOG(ERROR) << "Unhandled protocol message: " << json_message; |
| 101 } |
| 95 } | 102 } |
| 96 | 103 |
| 97 bool HeadlessDevToolsClientImpl::DispatchMessageReply( | 104 bool HeadlessDevToolsClientImpl::DispatchMessageReply( |
| 98 const base::DictionaryValue& message_dict) { | 105 const base::DictionaryValue& message_dict) { |
| 99 int id = 0; | 106 int id = 0; |
| 100 if (!message_dict.GetInteger("id", &id)) | 107 if (!message_dict.GetInteger("id", &id)) |
| 101 return false; | 108 return false; |
| 102 auto it = pending_messages_.find(id); | 109 auto it = pending_messages_.find(id); |
| 103 if (it == pending_messages_.end()) { | 110 if (it == pending_messages_.end()) { |
| 104 NOTREACHED() << "Unexpected reply"; | 111 NOTREACHED() << "Unexpected reply"; |
| 105 return false; | 112 return false; |
| 106 } | 113 } |
| 107 Callback callback = std::move(it->second); | 114 Callback callback = std::move(it->second); |
| 108 pending_messages_.erase(it); | 115 pending_messages_.erase(it); |
| 109 if (!callback.callback_with_result.is_null()) { | 116 if (!callback.callback_with_result.is_null()) { |
| 110 const base::DictionaryValue* result_dict; | 117 const base::DictionaryValue* result_dict; |
| 111 if (!message_dict.GetDictionary("result", &result_dict)) { | 118 if (!message_dict.GetDictionary("result", &result_dict)) { |
| 112 NOTREACHED() << "Badly formed reply result"; | 119 NOTREACHED() << "Badly formed reply result"; |
| 113 return false; | 120 return false; |
| 114 } | 121 } |
| 115 callback.callback_with_result.Run(*result_dict); | 122 callback.callback_with_result.Run(*result_dict); |
| 116 } else if (!callback.callback.is_null()) { | 123 } else if (!callback.callback.is_null()) { |
| 117 callback.callback.Run(); | 124 callback.callback.Run(); |
| 118 } | 125 } |
| 119 return true; | 126 return true; |
| 120 } | 127 } |
| 121 | 128 |
| 122 bool HeadlessDevToolsClientImpl::DispatchEvent( | 129 bool HeadlessDevToolsClientImpl::DispatchEvent( |
| 130 std::unique_ptr<base::Value> owning_message, |
| 123 const base::DictionaryValue& message_dict) { | 131 const base::DictionaryValue& message_dict) { |
| 124 std::string method; | 132 std::string method; |
| 125 if (!message_dict.GetString("method", &method)) | 133 if (!message_dict.GetString("method", &method)) |
| 126 return false; | 134 return false; |
| 127 auto it = event_handlers_.find(method); | 135 EventHandlerMap::const_iterator it = event_handlers_.find(method); |
| 128 if (it == event_handlers_.end()) { | 136 if (it == event_handlers_.end()) { |
| 129 NOTREACHED() << "Unknown event: " << method; | 137 NOTREACHED() << "Unknown event: " << method; |
| 130 return false; | 138 return false; |
| 131 } | 139 } |
| 132 if (!it->second.is_null()) { | 140 if (!it->second.is_null()) { |
| 133 const base::DictionaryValue* result_dict; | 141 const base::DictionaryValue* result_dict; |
| 134 if (!message_dict.GetDictionary("params", &result_dict)) { | 142 if (!message_dict.GetDictionary("params", &result_dict)) { |
| 135 NOTREACHED() << "Badly formed event parameters"; | 143 NOTREACHED() << "Badly formed event parameters"; |
| 136 return false; | 144 return false; |
| 137 } | 145 } |
| 138 it->second.Run(*result_dict); | 146 // DevTools assumes event handling is async so we must post a task here or |
| 147 // we risk breaking things. |
| 148 browser_main_thread_->PostTask( |
| 149 FROM_HERE, base::Bind(&HeadlessDevToolsClientImpl::DispatchEventTask, |
| 150 weak_ptr_factory_.GetWeakPtr(), |
| 151 base::Passed(std::move(owning_message)), |
| 152 &it->second, result_dict)); |
| 139 } | 153 } |
| 140 return true; | 154 return true; |
| 141 } | 155 } |
| 142 | 156 |
| 157 void HeadlessDevToolsClientImpl::DispatchEventTask( |
| 158 std::unique_ptr<base::Value> owning_message, |
| 159 const EventHandler* event_handler, |
| 160 const base::DictionaryValue* result_dict) { |
| 161 event_handler->Run(*result_dict); |
| 162 } |
| 163 |
| 143 void HeadlessDevToolsClientImpl::AgentHostClosed( | 164 void HeadlessDevToolsClientImpl::AgentHostClosed( |
| 144 content::DevToolsAgentHost* agent_host, | 165 content::DevToolsAgentHost* agent_host, |
| 145 bool replaced_with_another_client) { | 166 bool replaced_with_another_client) { |
| 146 DCHECK_EQ(agent_host_, agent_host); | 167 DCHECK_EQ(agent_host_, agent_host); |
| 147 agent_host = nullptr; | 168 agent_host = nullptr; |
| 148 pending_messages_.clear(); | 169 pending_messages_.clear(); |
| 149 } | 170 } |
| 150 | 171 |
| 151 accessibility::Domain* HeadlessDevToolsClientImpl::GetAccessibility() { | 172 accessibility::Domain* HeadlessDevToolsClientImpl::GetAccessibility() { |
| 152 return &accessibility_domain_; | 173 return &accessibility_domain_; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 HeadlessDevToolsClientImpl::Callback::Callback( | 368 HeadlessDevToolsClientImpl::Callback::Callback( |
| 348 base::Callback<void(const base::Value&)> callback) | 369 base::Callback<void(const base::Value&)> callback) |
| 349 : callback_with_result(callback) {} | 370 : callback_with_result(callback) {} |
| 350 | 371 |
| 351 HeadlessDevToolsClientImpl::Callback::~Callback() {} | 372 HeadlessDevToolsClientImpl::Callback::~Callback() {} |
| 352 | 373 |
| 353 HeadlessDevToolsClientImpl::Callback& HeadlessDevToolsClientImpl::Callback:: | 374 HeadlessDevToolsClientImpl::Callback& HeadlessDevToolsClientImpl::Callback:: |
| 354 operator=(Callback&& other) = default; | 375 operator=(Callback&& other) = default; |
| 355 | 376 |
| 356 } // namespace headless | 377 } // namespace headless |
| OLD | NEW |