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 |