1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "WebDevToolsAgentImpl.h"
33
34 #include "BoundObject.h"
35 #include "DebuggerAgentImpl.h"
36 #include "DebuggerAgentManager.h"
37 #include "Document.h"
38 #include "EventListener.h"
39 #include "InjectedScriptHost.h"
40 #include "InspectorBackend.h"
41 #include "InspectorController.h"
42 #include "InspectorFrontend.h"
43 #include "InspectorResource.h"
44 #include "Node.h"
45 #include "Page.h"
46 #include "PlatformString.h"
47 #include "ProfilerAgentImpl.h"
48 #include "ResourceError.h"
49 #include "ResourceRequest.h"
50 #include "ResourceResponse.h"
51 #include "ScriptObject.h"
52 #include "ScriptState.h"
53 #include "ScriptValue.h"
54 #include "V8Binding.h"
55 #include "V8InspectorBackend.h"
56 #include "V8Proxy.h"
57 #include "V8Utilities.h"
58 #include "WebDataSource.h"
59 #include "WebDevToolsAgentClient.h"
60 #include "WebDevToolsMessageData.h"
61 #include "WebFrameImpl.h"
62 #include "WebString.h"
63 #include "WebURL.h"
64 #include "WebURLError.h"
65 #include "WebURLRequest.h"
66 #include "WebURLResponse.h"
67 #include "WebViewImpl.h"
68 #include <wtf/Noncopyable.h>
69 #include <wtf/OwnPtr.h>
70
71 using WebCore::Document;
72 using WebCore::DocumentLoader;
73 using WebCore::FrameLoader;
74 using WebCore::InjectedScriptHost;
75 using WebCore::InspectorBackend;
76 using WebCore::InspectorController;
77 using WebCore::InspectorFrontend;
78 using WebCore::InspectorResource;
79 using WebCore::Node;
80 using WebCore::Page;
81 using WebCore::ResourceError;
82 using WebCore::ResourceRequest;
83 using WebCore::ResourceResponse;
84 using WebCore::SafeAllocation;
85 using WebCore::ScriptObject;
86 using WebCore::ScriptState;
87 using WebCore::ScriptValue;
88 using WebCore::String;
89 using WebCore::V8ClassIndex;
90 using WebCore::V8DOMWrapper;
91 using WebCore::V8InspectorBackend;
92 using WebCore::V8Proxy;
93
94 namespace WebKit {
95
96 namespace {
97
InspectorBackendWeakReferenceCallback(v8::Persistent<v8::Value> object,void * parameter)98 void InspectorBackendWeakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter)
99 {
100 InspectorBackend* backend = static_cast<InspectorBackend*>(parameter);
101 backend->deref();
102 object.Dispose();
103 }
104
SetApuAgentEnabledInUtilityContext(v8::Handle<v8::Context> context,bool enabled)105 void SetApuAgentEnabledInUtilityContext(v8::Handle<v8::Context> context, bool enabled)
106 {
107 v8::HandleScope handleScope;
108 v8::Context::Scope contextScope(context);
109 v8::Handle<v8::Object> dispatcher = v8::Local<v8::Object>::Cast(
110 context->Global()->Get(v8::String::New("ApuAgentDispatcher")));
111 if (dispatcher.IsEmpty())
112 return;
113 dispatcher->Set(v8::String::New("enabled"), v8::Boolean::New(enabled));
114 }
115
116 // TODO(pfeldman): Make this public in WebDevToolsAgent API.
117 static const char kApuAgentFeatureName[] = "apu-agent";
118
119 // Keep these in sync with the ones in inject_dispatch.js.
120 static const char kTimelineFeatureName[] = "timeline-profiler";
121 static const char kResourceTrackingFeatureName[] = "resource-tracking";
122
123 class IORPCDelegate : public DevToolsRPC::Delegate, public Noncopyable {
124 public:
IORPCDelegate()125 IORPCDelegate() { }
~IORPCDelegate()126 virtual ~IORPCDelegate() { }
sendRpcMessage(const WebDevToolsMessageData & data)127 virtual void sendRpcMessage(const WebDevToolsMessageData& data)
128 {
129 WebDevToolsAgentClient::sendMessageToFrontendOnIOThread(data);
130 }
131 };
132
133 } // namespace
134
WebDevToolsAgentImpl(WebViewImpl * webViewImpl,WebDevToolsAgentClient * client)135 WebDevToolsAgentImpl::WebDevToolsAgentImpl(
136 WebViewImpl* webViewImpl,
137 WebDevToolsAgentClient* client)
138 : m_hostId(client->hostIdentifier())
139 , m_client(client)
140 , m_webViewImpl(webViewImpl)
141 , m_apuAgentEnabled(false)
142 , m_resourceTrackingWasEnabled(false)
143 , m_attached(false)
144 {
145 m_debuggerAgentDelegateStub.set(new DebuggerAgentDelegateStub(this));
146 m_toolsAgentDelegateStub.set(new ToolsAgentDelegateStub(this));
147 m_apuAgentDelegateStub.set(new ApuAgentDelegateStub(this));
148 }
149
~WebDevToolsAgentImpl()150 WebDevToolsAgentImpl::~WebDevToolsAgentImpl()
151 {
152 DebuggerAgentManager::onWebViewClosed(m_webViewImpl);
153 disposeUtilityContext();
154 }
155
disposeUtilityContext()156 void WebDevToolsAgentImpl::disposeUtilityContext()
157 {
158 if (!m_utilityContext.IsEmpty()) {
159 m_utilityContext.Dispose();
160 m_utilityContext.Clear();
161 }
162 }
163
unhideResourcesPanelIfNecessary()164 void WebDevToolsAgentImpl::unhideResourcesPanelIfNecessary()
165 {
166 InspectorController* ic = m_webViewImpl->page()->inspectorController();
167 ic->ensureResourceTrackingSettingsLoaded();
168 String command = String::format("[\"setResourcesPanelEnabled\", %s]",
169 ic->resourceTrackingEnabled() ? "true" : "false");
170 m_toolsAgentDelegateStub->dispatchOnClient(command);
171 }
172
attach()173 void WebDevToolsAgentImpl::attach()
174 {
175 if (m_attached)
176 return;
177 m_debuggerAgentImpl.set(
178 new DebuggerAgentImpl(m_webViewImpl,
179 m_debuggerAgentDelegateStub.get(),
180 this));
181 resetInspectorFrontendProxy();
182 unhideResourcesPanelIfNecessary();
183 // Allow controller to send messages to the frontend.
184 InspectorController* ic = inspectorController();
185
186 { // TODO(yurys): the source should have already been pushed by the frontend.
187 v8::HandleScope scope;
188 v8::Context::Scope contextScope(m_utilityContext);
189 v8::Handle<v8::Value> constructorValue = m_utilityContext->Global()->Get(
190 v8::String::New("injectedScriptConstructor"));
191 if (constructorValue->IsFunction()) {
192 String source = WebCore::toWebCoreString(constructorValue);
193 ic->injectedScriptHost()->setInjectedScriptSource("(" + source + ")");
194 }
195 }
196
197 ic->setWindowVisible(true, false);
198 m_attached = true;
199 }
200
detach()201 void WebDevToolsAgentImpl::detach()
202 {
203 // Prevent controller from sending messages to the frontend.
204 InspectorController* ic = m_webViewImpl->page()->inspectorController();
205 ic->hideHighlight();
206 ic->close();
207 disposeUtilityContext();
208 m_debuggerAgentImpl.set(0);
209 m_attached = false;
210 m_apuAgentEnabled = false;
211 }
212
didNavigate()213 void WebDevToolsAgentImpl::didNavigate()
214 {
215 DebuggerAgentManager::onNavigate();
216 }
217
didCommitProvisionalLoad(WebFrameImpl * webframe,bool isNewNavigation)218 void WebDevToolsAgentImpl::didCommitProvisionalLoad(WebFrameImpl* webframe, bool isNewNavigation)
219 {
220 if (!m_attached)
221 return;
222 WebDataSource* ds = webframe->dataSource();
223 const WebURLRequest& request = ds->request();
224 WebURL url = ds->hasUnreachableURL() ?
225 ds->unreachableURL() :
226 request.url();
227 if (!webframe->parent()) {
228 resetInspectorFrontendProxy();
229 m_toolsAgentDelegateStub->frameNavigate(WebCore::KURL(url).string());
230 SetApuAgentEnabledInUtilityContext(m_utilityContext, m_apuAgentEnabled);
231 unhideResourcesPanelIfNecessary();
232 }
233 }
234
didClearWindowObject(WebFrameImpl * webframe)235 void WebDevToolsAgentImpl::didClearWindowObject(WebFrameImpl* webframe)
236 {
237 DebuggerAgentManager::setHostId(webframe, m_hostId);
238 if (m_attached) {
239 // Push context id into the client if it is already attached.
240 m_debuggerAgentDelegateStub->setContextId(m_hostId);
241 }
242 }
243
forceRepaint()244 void WebDevToolsAgentImpl::forceRepaint()
245 {
246 m_client->forceRepaint();
247 }
248
dispatchOnInspectorController(int callId,const String & functionName,const String & jsonArgs)249 void WebDevToolsAgentImpl::dispatchOnInspectorController(int callId, const String& functionName, const String& jsonArgs)
250 {
251 String result;
252 String exception;
253 result = m_debuggerAgentImpl->executeUtilityFunction(m_utilityContext, callId,
254 "InspectorControllerDispatcher", functionName, jsonArgs, false /* is sync */, &exception);
255 m_toolsAgentDelegateStub->didDispatchOn(callId, result, exception);
256 }
257
dispatchOnInjectedScript(int callId,int injectedScriptId,const String & functionName,const String & jsonArgs,bool async)258 void WebDevToolsAgentImpl::dispatchOnInjectedScript(int callId, int injectedScriptId, const String& functionName, const String& jsonArgs, bool async)
259 {
260 inspectorController()->inspectorBackend()->dispatchOnInjectedScript(
261 callId,
262 injectedScriptId,
263 functionName,
264 jsonArgs,
265 async);
266 }
267
dispatchMessageFromFrontend(const WebDevToolsMessageData & data)268 void WebDevToolsAgentImpl::dispatchMessageFromFrontend(const WebDevToolsMessageData& data)
269 {
270 if (ToolsAgentDispatch::dispatch(this, data))
271 return;
272
273 if (!m_attached)
274 return;
275
276 if (m_debuggerAgentImpl.get() && DebuggerAgentDispatch::dispatch(m_debuggerAgentImpl.get(), data))
277 return;
278 }
279
inspectElementAt(const WebPoint & point)280 void WebDevToolsAgentImpl::inspectElementAt(const WebPoint& point)
281 {
282 m_webViewImpl->inspectElementAt(point);
283 }
284
setRuntimeFeatureEnabled(const WebString & feature,bool enabled)285 void WebDevToolsAgentImpl::setRuntimeFeatureEnabled(const WebString& feature, bool enabled)
286 {
287 if (feature == kApuAgentFeatureName)
288 setApuAgentEnabled(enabled);
289 else if (feature == kTimelineFeatureName)
290 setTimelineProfilingEnabled(enabled);
291 else if (feature == kResourceTrackingFeatureName) {
292 InspectorController* ic = m_webViewImpl->page()->inspectorController();
293 if (enabled)
294 ic->enableResourceTracking(false /* not sticky */, false /* no reload */);
295 else
296 ic->disableResourceTracking(false /* not sticky */);
297 }
298 }
299
sendRpcMessage(const WebDevToolsMessageData & data)300 void WebDevToolsAgentImpl::sendRpcMessage(const WebDevToolsMessageData& data)
301 {
302 m_client->sendMessageToFrontend(data);
303 }
304
compileUtilityScripts()305 void WebDevToolsAgentImpl::compileUtilityScripts()
306 {
307 v8::HandleScope handleScope;
308 v8::Context::Scope contextScope(m_utilityContext);
309 // Inject javascript into the context.
310 WebCString injectedScriptJs = m_client->injectedScriptSource();
311 v8::Script::Compile(v8::String::New(
312 injectedScriptJs.data(),
313 injectedScriptJs.length()))->Run();
314 WebCString injectDispatchJs = m_client->injectedScriptDispatcherSource();
315 v8::Script::Compile(v8::String::New(
316 injectDispatchJs.data(),
317 injectDispatchJs.length()))->Run();
318 }
319
initDevToolsAgentHost()320 void WebDevToolsAgentImpl::initDevToolsAgentHost()
321 {
322 BoundObject devtoolsAgentHost(m_utilityContext, this, "DevToolsAgentHost");
323 devtoolsAgentHost.addProtoFunction(
324 "dispatch",
325 WebDevToolsAgentImpl::jsDispatchOnClient);
326 devtoolsAgentHost.addProtoFunction(
327 "dispatchToApu",
328 WebDevToolsAgentImpl::jsDispatchToApu);
329 devtoolsAgentHost.addProtoFunction(
330 "evaluateOnSelf",
331 WebDevToolsAgentImpl::jsEvaluateOnSelf);
332 devtoolsAgentHost.addProtoFunction(
333 "runtimeFeatureStateChanged",
334 WebDevToolsAgentImpl::jsOnRuntimeFeatureStateChanged);
335 devtoolsAgentHost.build();
336
337 v8::HandleScope scope;
338 v8::Context::Scope utilityScope(m_utilityContext);
339 // Call custom code to create inspector backend wrapper in the utility context
340 // instead of calling V8DOMWrapper::convertToV8Object that would create the
341 // wrapper in the Page main frame context.
342 v8::Handle<v8::Object> backendWrapper = createInspectorBackendV8Wrapper();
343 if (backendWrapper.IsEmpty())
344 return;
345 m_utilityContext->Global()->Set(v8::String::New("InspectorBackend"), backendWrapper);
346 }
347
createInspectorBackendV8Wrapper()348 v8::Local<v8::Object> WebDevToolsAgentImpl::createInspectorBackendV8Wrapper()
349 {
350 V8ClassIndex::V8WrapperType descriptorType = V8ClassIndex::INSPECTORBACKEND;
351 v8::Handle<v8::Function> function = V8InspectorBackend::GetTemplate()->GetFunction();
352 if (function.IsEmpty()) {
353 // Return if allocation failed.
354 return v8::Local<v8::Object>();
355 }
356 v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
357 if (instance.IsEmpty()) {
358 // Avoid setting the wrapper if allocation failed.
359 return v8::Local<v8::Object>();
360 }
361 InspectorBackend* backend = m_webViewImpl->page()->inspectorController()->inspectorBackend();
362 V8DOMWrapper::setDOMWrapper(instance, V8ClassIndex::ToInt(descriptorType), backend);
363 // Create a weak reference to the v8 wrapper of InspectorBackend to deref
364 // InspectorBackend when the wrapper is garbage collected.
365 backend->ref();
366 v8::Persistent<v8::Object> weakHandle = v8::Persistent<v8::Object>::New(instance);
367 weakHandle.MakeWeak(backend, &InspectorBackendWeakReferenceCallback);
368 return instance;
369 }
370
resetInspectorFrontendProxy()371 void WebDevToolsAgentImpl::resetInspectorFrontendProxy()
372 {
373 disposeUtilityContext();
374 m_debuggerAgentImpl->createUtilityContext(m_webViewImpl->page()->mainFrame(), &m_utilityContext);
375 compileUtilityScripts();
376 initDevToolsAgentHost();
377
378 v8::HandleScope scope;
379 v8::Context::Scope contextScope(m_utilityContext);
380 ScriptState* state = ScriptState::forContext(
381 v8::Local<v8::Context>::New(m_utilityContext));
382 InspectorController* ic = inspectorController();
383 ic->setFrontendProxyObject(state, ScriptObject(state, m_utilityContext->Global()));
384 }
385
setApuAgentEnabled(bool enabled)386 void WebDevToolsAgentImpl::setApuAgentEnabled(bool enabled)
387 {
388 m_apuAgentEnabled = enabled;
389 SetApuAgentEnabledInUtilityContext(m_utilityContext, enabled);
390 InspectorController* ic = m_webViewImpl->page()->inspectorController();
391 if (enabled) {
392 m_resourceTrackingWasEnabled = ic->resourceTrackingEnabled();
393 ic->startTimelineProfiler();
394 if (!m_resourceTrackingWasEnabled) {
395 // TODO(knorton): Introduce some kind of agents dependency here so that
396 // user could turn off resource tracking while apu agent is on.
397 ic->enableResourceTracking(false, false);
398 }
399 m_debuggerAgentImpl->setAutoContinueOnException(true);
400 } else {
401 ic->stopTimelineProfiler();
402 if (!m_resourceTrackingWasEnabled)
403 ic->disableResourceTracking(false);
404 m_resourceTrackingWasEnabled = false;
405 }
406 m_client->runtimeFeatureStateChanged(
407 kApuAgentFeatureName,
408 enabled);
409 }
410
411 // static
jsDispatchOnClient(const v8::Arguments & args)412 v8::Handle<v8::Value> WebDevToolsAgentImpl::jsDispatchOnClient(const v8::Arguments& args)
413 {
414 v8::TryCatch exceptionCatcher;
415 String message = WebCore::toWebCoreStringWithNullCheck(args[0]);
416 if (message.isEmpty() || exceptionCatcher.HasCaught())
417 return v8::Undefined();
418 WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value());
419 agent->m_toolsAgentDelegateStub->dispatchOnClient(message);
420 return v8::Undefined();
421 }
422
423 // static
jsDispatchToApu(const v8::Arguments & args)424 v8::Handle<v8::Value> WebDevToolsAgentImpl::jsDispatchToApu(const v8::Arguments& args)
425 {
426 v8::TryCatch exceptionCatcher;
427 String message = WebCore::toWebCoreStringWithNullCheck(args[0]);
428 if (message.isEmpty() || exceptionCatcher.HasCaught())
429 return v8::Undefined();
430 WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(
431 v8::External::Cast(*args.Data())->Value());
432 agent->m_apuAgentDelegateStub->dispatchToApu(message);
433 return v8::Undefined();
434 }
435
436 // static
jsEvaluateOnSelf(const v8::Arguments & args)437 v8::Handle<v8::Value> WebDevToolsAgentImpl::jsEvaluateOnSelf(const v8::Arguments& args)
438 {
439 String code;
440 {
441 v8::TryCatch exceptionCatcher;
442 code = WebCore::toWebCoreStringWithNullCheck(args[0]);
443 if (code.isEmpty() || exceptionCatcher.HasCaught())
444 return v8::Undefined();
445 }
446 WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value());
447 v8::Context::Scope(agent->m_utilityContext);
448 V8Proxy* proxy = V8Proxy::retrieve(agent->m_webViewImpl->page()->mainFrame());
449 v8::Local<v8::Value> result = proxy->runScript(v8::Script::Compile(v8::String::New(code.utf8().data())), true);
450 return result;
451 }
452
453 // static
jsOnRuntimeFeatureStateChanged(const v8::Arguments & args)454 v8::Handle<v8::Value> WebDevToolsAgentImpl::jsOnRuntimeFeatureStateChanged(const v8::Arguments& args)
455 {
456 v8::TryCatch exceptionCatcher;
457 String feature = WebCore::toWebCoreStringWithNullCheck(args[0]);
458 bool enabled = args[1]->ToBoolean()->Value();
459 if (feature.isEmpty() || exceptionCatcher.HasCaught())
460 return v8::Undefined();
461 WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value());
462 agent->m_client->runtimeFeatureStateChanged(feature, enabled);
463 return v8::Undefined();
464 }
465
466
inspectorController()467 WebCore::InspectorController* WebDevToolsAgentImpl::inspectorController()
468 {
469 if (Page* page = m_webViewImpl->page())
470 return page->inspectorController();
471 return 0;
472 }
473
474
475 //------- plugin resource load notifications ---------------
identifierForInitialRequest(unsigned long resourceId,WebFrame * frame,const WebURLRequest & request)476 void WebDevToolsAgentImpl::identifierForInitialRequest(
477 unsigned long resourceId,
478 WebFrame* frame,
479 const WebURLRequest& request)
480 {
481 if (InspectorController* ic = inspectorController()) {
482 WebFrameImpl* webFrameImpl = static_cast<WebFrameImpl*>(frame);
483 FrameLoader* frameLoader = webFrameImpl->frame()->loader();
484 DocumentLoader* loader = frameLoader->activeDocumentLoader();
485 ic->identifierForInitialRequest(resourceId, loader, request.toResourceRequest());
486 }
487 }
488
willSendRequest(unsigned long resourceId,const WebURLRequest & request)489 void WebDevToolsAgentImpl::willSendRequest(unsigned long resourceId, const WebURLRequest& request)
490 {
491 if (InspectorController* ic = inspectorController())
492 ic->willSendRequest(resourceId, request.toResourceRequest(), ResourceResponse());
493 }
494
didReceiveData(unsigned long resourceId,int length)495 void WebDevToolsAgentImpl::didReceiveData(unsigned long resourceId, int length)
496 {
497 if (InspectorController* ic = inspectorController())
498 ic->didReceiveContentLength(resourceId, length);
499 }
500
didReceiveResponse(unsigned long resourceId,const WebURLResponse & response)501 void WebDevToolsAgentImpl::didReceiveResponse(unsigned long resourceId, const WebURLResponse& response)
502 {
503 if (InspectorController* ic = inspectorController())
504 ic->didReceiveResponse(resourceId, response.toResourceResponse());
505 }
506
didFinishLoading(unsigned long resourceId)507 void WebDevToolsAgentImpl::didFinishLoading(unsigned long resourceId)
508 {
509 if (InspectorController* ic = inspectorController())
510 ic->didFinishLoading(resourceId);
511 }
512
didFailLoading(unsigned long resourceId,const WebURLError & error)513 void WebDevToolsAgentImpl::didFailLoading(unsigned long resourceId, const WebURLError& error)
514 {
515 ResourceError resourceError;
516 if (InspectorController* ic = inspectorController())
517 ic->didFailLoading(resourceId, resourceError);
518 }
519
evaluateInWebInspector(long callId,const WebString & script)520 void WebDevToolsAgentImpl::evaluateInWebInspector(long callId, const WebString& script)
521 {
522 InspectorController* ic = inspectorController();
523 ic->evaluateForTestInFrontend(callId, script);
524 }
525
setTimelineProfilingEnabled(bool enabled)526 void WebDevToolsAgentImpl::setTimelineProfilingEnabled(bool enabled)
527 {
528 InspectorController* ic = inspectorController();
529 if (enabled)
530 ic->startTimelineProfiler();
531 else
532 ic->stopTimelineProfiler();
533 }
534
create(WebView * webview,WebDevToolsAgentClient * client)535 WebDevToolsAgent* WebDevToolsAgent::create(WebView* webview, WebDevToolsAgentClient* client)
536 {
537 return new WebDevToolsAgentImpl(static_cast<WebViewImpl*>(webview), client);
538 }
539
executeDebuggerCommand(const WebString & command,int callerId)540 void WebDevToolsAgent::executeDebuggerCommand(const WebString& command, int callerId)
541 {
542 DebuggerAgentManager::executeDebuggerCommand(command, callerId);
543 }
544
debuggerPauseScript()545 void WebDevToolsAgent::debuggerPauseScript()
546 {
547 DebuggerAgentManager::pauseScript();
548 }
549
setMessageLoopDispatchHandler(MessageLoopDispatchHandler handler)550 void WebDevToolsAgent::setMessageLoopDispatchHandler(MessageLoopDispatchHandler handler)
551 {
552 DebuggerAgentManager::setMessageLoopDispatchHandler(handler);
553 }
554
dispatchMessageFromFrontendOnIOThread(const WebDevToolsMessageData & data)555 bool WebDevToolsAgent::dispatchMessageFromFrontendOnIOThread(const WebDevToolsMessageData& data)
556 {
557 IORPCDelegate transport;
558 ProfilerAgentDelegateStub stub(&transport);
559 ProfilerAgentImpl agent(&stub);
560 return ProfilerAgentDispatch::dispatch(&agent, data);
561 }
562
563 } // namespace WebKit
564