WebKit/chromium/src/WebDevToolsAgentImpl.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 "PageGroup.h"
       
    47 #include "PlatformString.h"
       
    48 #include "ProfilerAgentImpl.h"
       
    49 #include "ResourceError.h"
       
    50 #include "ResourceRequest.h"
       
    51 #include "ResourceResponse.h"
       
    52 #include "ScriptDebugServer.h"
       
    53 #include "ScriptObject.h"
       
    54 #include "ScriptState.h"
       
    55 #include "ScriptValue.h"
       
    56 #include "V8Binding.h"
       
    57 #include "V8InspectorBackend.h"
       
    58 #include "V8Proxy.h"
       
    59 #include "V8Utilities.h"
       
    60 #include "WebDataSource.h"
       
    61 #include "WebDevToolsAgentClient.h"
       
    62 #include "WebDevToolsMessageData.h"
       
    63 #include "WebDevToolsMessageTransport.h"
       
    64 #include "WebFrameImpl.h"
       
    65 #include "WebRect.h"
       
    66 #include "WebString.h"
       
    67 #include "WebURL.h"
       
    68 #include "WebURLError.h"
       
    69 #include "WebURLRequest.h"
       
    70 #include "WebURLResponse.h"
       
    71 #include "WebViewClient.h"
       
    72 #include "WebViewImpl.h"
       
    73 #include <wtf/Noncopyable.h>
       
    74 #include <wtf/OwnPtr.h>
       
    75 
       
    76 using WebCore::Document;
       
    77 using WebCore::DocumentLoader;
       
    78 using WebCore::FrameLoader;
       
    79 using WebCore::InjectedScriptHost;
       
    80 using WebCore::InspectorBackend;
       
    81 using WebCore::InspectorController;
       
    82 using WebCore::InspectorFrontend;
       
    83 using WebCore::InspectorResource;
       
    84 using WebCore::Node;
       
    85 using WebCore::Page;
       
    86 using WebCore::ResourceError;
       
    87 using WebCore::ResourceRequest;
       
    88 using WebCore::ResourceResponse;
       
    89 using WebCore::SafeAllocation;
       
    90 using WebCore::ScriptObject;
       
    91 using WebCore::ScriptState;
       
    92 using WebCore::ScriptValue;
       
    93 using WebCore::String;
       
    94 using WebCore::V8DOMWrapper;
       
    95 using WebCore::V8InspectorBackend;
       
    96 using WebCore::V8Proxy;
       
    97 
       
    98 namespace WebKit {
       
    99 
       
   100 namespace {
       
   101 
       
   102 void InspectorBackendWeakReferenceCallback(v8::Persistent<v8::Value> object, void* parameter)
       
   103 {
       
   104     InspectorBackend* backend = static_cast<InspectorBackend*>(parameter);
       
   105     backend->deref();
       
   106     object.Dispose();
       
   107 }
       
   108 
       
   109 static const char kResourceTrackingFeatureName[] = "resource-tracking";
       
   110 static const char kTimelineFeatureName[] = "timeline-profiler";
       
   111 static const char kApuAgentFeatureName[] = "apu-agent";
       
   112 
       
   113 class IORPCDelegate : public DevToolsRPC::Delegate, public Noncopyable {
       
   114 public:
       
   115     IORPCDelegate() : m_transport(0) { }
       
   116     explicit IORPCDelegate(WebDevToolsMessageTransport* transport) : m_transport(transport) { }
       
   117     virtual ~IORPCDelegate() { }
       
   118     virtual void sendRpcMessage(const WebDevToolsMessageData& data)
       
   119     {
       
   120         if (m_transport)
       
   121             m_transport->sendMessageToFrontendOnIOThread(data);
       
   122     }
       
   123 
       
   124 private:
       
   125     WebDevToolsMessageTransport* m_transport;
       
   126 };
       
   127 
       
   128 class ClientMessageLoopAdapter : public WebCore::ScriptDebugServer::ClientMessageLoop {
       
   129 public:
       
   130     static void ensureClientMessageLoopCreated(WebDevToolsAgentClient* client)
       
   131     {
       
   132         if (s_instance)
       
   133             return;
       
   134         s_instance = new ClientMessageLoopAdapter(client->createClientMessageLoop());
       
   135         WebCore::ScriptDebugServer::shared().setClientMessageLoop(s_instance);
       
   136     }
       
   137 
       
   138     static void inspectedViewClosed(WebViewImpl* view)
       
   139     {
       
   140         if (s_instance)
       
   141             s_instance->m_frozenViews.remove(view);
       
   142     }
       
   143 
       
   144     static void didNavigate()
       
   145     {
       
   146         // Release render thread if necessary.
       
   147         if (s_instance && s_instance->m_running)
       
   148             WebCore::ScriptDebugServer::shared().continueProgram();
       
   149     }
       
   150 
       
   151 private:
       
   152     ClientMessageLoopAdapter(PassOwnPtr<WebKit::WebDevToolsAgentClient::WebKitClientMessageLoop> messageLoop)
       
   153         : m_running(false)
       
   154         , m_messageLoop(messageLoop) { }
       
   155 
       
   156 
       
   157     virtual void run(Page* page)
       
   158     {
       
   159         if (m_running)
       
   160             return;
       
   161         m_running = true;
       
   162 
       
   163         Vector<WebViewImpl*> views;
       
   164 
       
   165         // 1. Disable input events.
       
   166         HashSet<Page*>::const_iterator end =  page->group().pages().end();
       
   167         for (HashSet<Page*>::const_iterator it =  page->group().pages().begin(); it != end; ++it) {
       
   168             WebViewImpl* view = WebViewImpl::fromPage(*it);
       
   169             m_frozenViews.add(view);
       
   170             views.append(view);
       
   171             view->setIgnoreInputEvents(true);
       
   172         }
       
   173 
       
   174         // 2. Disable active objects
       
   175         WebView::willEnterModalLoop();
       
   176 
       
   177         // 3. Process messages until quitNow is called.
       
   178         m_messageLoop->run();
       
   179 
       
   180         // 4. Resume active objects
       
   181         WebView::didExitModalLoop();
       
   182 
       
   183         // 5. Resume input events.
       
   184         for (Vector<WebViewImpl*>::iterator it = views.begin(); it != views.end(); ++it) {
       
   185             if (m_frozenViews.contains(*it)) {
       
   186                 // The view was not closed during the dispatch.
       
   187                 (*it)->setIgnoreInputEvents(false);
       
   188             }
       
   189         }
       
   190 
       
   191         // 6. All views have been resumed, clear the set.
       
   192         m_frozenViews.clear();
       
   193 
       
   194         m_running = false;
       
   195     }
       
   196 
       
   197     virtual void quitNow()
       
   198     {
       
   199         m_messageLoop->quitNow();
       
   200     }
       
   201 
       
   202     bool m_running;
       
   203     OwnPtr<WebKit::WebDevToolsAgentClient::WebKitClientMessageLoop> m_messageLoop;
       
   204     typedef HashSet<WebViewImpl*> FrozenViewsSet;
       
   205     FrozenViewsSet m_frozenViews;
       
   206     static ClientMessageLoopAdapter* s_instance;
       
   207 
       
   208 };
       
   209 
       
   210 ClientMessageLoopAdapter* ClientMessageLoopAdapter::s_instance = 0;
       
   211 
       
   212 } //  namespace
       
   213 
       
   214 WebDevToolsAgentImpl::WebDevToolsAgentImpl(
       
   215     WebViewImpl* webViewImpl,
       
   216     WebDevToolsAgentClient* client)
       
   217     : m_hostId(client->hostIdentifier())
       
   218     , m_client(client)
       
   219     , m_webViewImpl(webViewImpl)
       
   220     , m_apuAgentEnabled(false)
       
   221     , m_resourceTrackingWasEnabled(false)
       
   222     , m_attached(false)
       
   223 {
       
   224     DebuggerAgentManager::setExposeV8DebuggerProtocol(
       
   225         client->exposeV8DebuggerProtocol());
       
   226     m_debuggerAgentDelegateStub.set(new DebuggerAgentDelegateStub(this));
       
   227     m_toolsAgentDelegateStub.set(new ToolsAgentDelegateStub(this));
       
   228     m_apuAgentDelegateStub.set(new ApuAgentDelegateStub(this));
       
   229 }
       
   230 
       
   231 WebDevToolsAgentImpl::~WebDevToolsAgentImpl()
       
   232 {
       
   233     DebuggerAgentManager::onWebViewClosed(m_webViewImpl);
       
   234     ClientMessageLoopAdapter::inspectedViewClosed(m_webViewImpl);
       
   235     disposeUtilityContext();
       
   236 }
       
   237 
       
   238 void WebDevToolsAgentImpl::disposeUtilityContext()
       
   239 {
       
   240     if (!m_utilityContext.IsEmpty()) {
       
   241         m_utilityContext.Dispose();
       
   242         m_utilityContext.Clear();
       
   243     }
       
   244 }
       
   245 
       
   246 void WebDevToolsAgentImpl::attach()
       
   247 {
       
   248     if (m_attached)
       
   249         return;
       
   250 
       
   251     if (!m_client->exposeV8DebuggerProtocol())
       
   252         ClientMessageLoopAdapter::ensureClientMessageLoopCreated(m_client);
       
   253 
       
   254     m_debuggerAgentImpl.set(
       
   255         new DebuggerAgentImpl(m_webViewImpl,
       
   256                               m_debuggerAgentDelegateStub.get(),
       
   257                               this));
       
   258     createInspectorFrontendProxy();
       
   259 
       
   260     // Allow controller to send messages to the frontend.
       
   261     InspectorController* ic = inspectorController();
       
   262 
       
   263     { // TODO(yurys): the source should have already been pushed by the frontend.
       
   264         v8::HandleScope scope;
       
   265         v8::Context::Scope contextScope(m_utilityContext);
       
   266         v8::Handle<v8::Value> constructorValue = m_utilityContext->Global()->Get(
       
   267             v8::String::New("injectedScriptConstructor"));
       
   268         if (constructorValue->IsFunction()) {
       
   269             String source = WebCore::toWebCoreString(constructorValue);
       
   270             ic->injectedScriptHost()->setInjectedScriptSource("(" + source + ")");
       
   271         }
       
   272     }
       
   273 
       
   274     setInspectorFrontendProxyToInspectorController();
       
   275     m_attached = true;
       
   276 }
       
   277 
       
   278 void WebDevToolsAgentImpl::detach()
       
   279 {
       
   280     // Prevent controller from sending messages to the frontend.
       
   281     InspectorController* ic = m_webViewImpl->page()->inspectorController();
       
   282     ic->disconnectFrontend();
       
   283     ic->hideHighlight();
       
   284     ic->close();
       
   285     disposeUtilityContext();
       
   286     m_debuggerAgentImpl.set(0);
       
   287     m_attached = false;
       
   288     m_apuAgentEnabled = false;
       
   289 }
       
   290 
       
   291 void WebDevToolsAgentImpl::didNavigate()
       
   292 {
       
   293     ClientMessageLoopAdapter::didNavigate();
       
   294     DebuggerAgentManager::onNavigate();
       
   295 }
       
   296 
       
   297 void WebDevToolsAgentImpl::didClearWindowObject(WebFrameImpl* webframe)
       
   298 {
       
   299     DebuggerAgentManager::setHostId(webframe, m_hostId);
       
   300     if (m_attached) {
       
   301         // Push context id into the client if it is already attached.
       
   302         m_debuggerAgentDelegateStub->setContextId(m_hostId);
       
   303     }
       
   304 }
       
   305 
       
   306 void WebDevToolsAgentImpl::forceRepaint()
       
   307 {
       
   308     m_client->forceRepaint();
       
   309 }
       
   310 
       
   311 void WebDevToolsAgentImpl::dispatchOnInspectorController(int callId, const String& functionName, const String& jsonArgs)
       
   312 {
       
   313     String result;
       
   314     String exception;
       
   315     result = m_debuggerAgentImpl->executeUtilityFunction(m_utilityContext, callId,
       
   316         "InspectorControllerDispatcher", functionName, jsonArgs, false /* is sync */, &exception);
       
   317     m_toolsAgentDelegateStub->didDispatchOn(callId, result, exception);
       
   318 }
       
   319 
       
   320 void WebDevToolsAgentImpl::dispatchOnInjectedScript(int callId, int injectedScriptId, const String& functionName, const String& jsonArgs, bool async)
       
   321 {
       
   322     inspectorController()->inspectorBackend()->dispatchOnInjectedScript(
       
   323         callId,
       
   324         injectedScriptId,
       
   325         functionName,
       
   326         jsonArgs,
       
   327         async);
       
   328 }
       
   329 
       
   330 void WebDevToolsAgentImpl::dispatchMessageFromFrontend(const WebDevToolsMessageData& data)
       
   331 {
       
   332     if (ToolsAgentDispatch::dispatch(this, data))
       
   333         return;
       
   334 
       
   335     if (!m_attached)
       
   336         return;
       
   337 
       
   338     if (m_debuggerAgentImpl.get() && DebuggerAgentDispatch::dispatch(m_debuggerAgentImpl.get(), data))
       
   339         return;
       
   340 }
       
   341 
       
   342 void WebDevToolsAgentImpl::inspectElementAt(const WebPoint& point)
       
   343 {
       
   344     m_webViewImpl->inspectElementAt(point);
       
   345 }
       
   346 
       
   347 void WebDevToolsAgentImpl::setRuntimeFeatureEnabled(const WebString& feature, bool enabled)
       
   348 {
       
   349     if (feature == kApuAgentFeatureName)
       
   350         setApuAgentEnabled(enabled);
       
   351     else if (feature == kTimelineFeatureName)
       
   352         setTimelineProfilingEnabled(enabled);
       
   353     else if (feature == kResourceTrackingFeatureName) {
       
   354         InspectorController* ic = m_webViewImpl->page()->inspectorController();
       
   355         if (enabled)
       
   356           ic->enableResourceTracking(false /* not sticky */, false /* no reload */);
       
   357         else
       
   358           ic->disableResourceTracking(false /* not sticky */);
       
   359     }
       
   360 }
       
   361 
       
   362 void WebDevToolsAgentImpl::sendRpcMessage(const WebDevToolsMessageData& data)
       
   363 {
       
   364     m_client->sendMessageToFrontend(data);
       
   365 }
       
   366 
       
   367 void WebDevToolsAgentImpl::compileUtilityScripts()
       
   368 {
       
   369     v8::HandleScope handleScope;
       
   370     v8::Context::Scope contextScope(m_utilityContext);
       
   371     // Inject javascript into the context.
       
   372     WebCString injectedScriptJs = m_client->injectedScriptSource();
       
   373     v8::Script::Compile(v8::String::New(
       
   374         injectedScriptJs.data(),
       
   375         injectedScriptJs.length()))->Run();
       
   376     WebCString injectDispatchJs = m_client->injectedScriptDispatcherSource();
       
   377     v8::Script::Compile(v8::String::New(
       
   378         injectDispatchJs.data(),
       
   379         injectDispatchJs.length()))->Run();
       
   380 }
       
   381 
       
   382 void WebDevToolsAgentImpl::initDevToolsAgentHost()
       
   383 {
       
   384     BoundObject devtoolsAgentHost(m_utilityContext, this, "DevToolsAgentHost");
       
   385     devtoolsAgentHost.addProtoFunction(
       
   386         "dispatch",
       
   387         WebDevToolsAgentImpl::jsDispatchOnClient);
       
   388     devtoolsAgentHost.build();
       
   389 
       
   390     v8::HandleScope scope;
       
   391     v8::Context::Scope utilityScope(m_utilityContext);
       
   392     // Call custom code to create inspector backend wrapper in the utility context
       
   393     // instead of calling V8DOMWrapper::convertToV8Object that would create the
       
   394     // wrapper in the Page main frame context.
       
   395     v8::Handle<v8::Object> backendWrapper = createInspectorBackendV8Wrapper();
       
   396     if (backendWrapper.IsEmpty())
       
   397         return;
       
   398     m_utilityContext->Global()->Set(v8::String::New("InspectorBackend"), backendWrapper);
       
   399 }
       
   400 
       
   401 v8::Local<v8::Object> WebDevToolsAgentImpl::createInspectorBackendV8Wrapper()
       
   402 {
       
   403     v8::Handle<v8::Function> function = V8InspectorBackend::GetTemplate()->GetFunction();
       
   404     if (function.IsEmpty()) {
       
   405         // Return if allocation failed.
       
   406         return v8::Local<v8::Object>();
       
   407     }
       
   408     v8::Local<v8::Object> instance = SafeAllocation::newInstance(function);
       
   409     if (instance.IsEmpty()) {
       
   410         // Avoid setting the wrapper if allocation failed.
       
   411         return v8::Local<v8::Object>();
       
   412     }
       
   413     InspectorBackend* backend = m_webViewImpl->page()->inspectorController()->inspectorBackend();
       
   414     V8DOMWrapper::setDOMWrapper(instance, &V8InspectorBackend::info, backend);
       
   415     // Create a weak reference to the v8 wrapper of InspectorBackend to deref
       
   416     // InspectorBackend when the wrapper is garbage collected.
       
   417     backend->ref();
       
   418     v8::Persistent<v8::Object> weakHandle = v8::Persistent<v8::Object>::New(instance);
       
   419     weakHandle.MakeWeak(backend, &InspectorBackendWeakReferenceCallback);
       
   420     return instance;
       
   421 }
       
   422 
       
   423 void WebDevToolsAgentImpl::createInspectorFrontendProxy()
       
   424 {
       
   425     disposeUtilityContext();
       
   426     m_utilityContext = v8::Context::New();
       
   427     compileUtilityScripts();
       
   428     initDevToolsAgentHost();
       
   429     WebCString debuggerScriptJs = m_client->debuggerScriptSource();
       
   430     WebCore::ScriptDebugServer::shared().setDebuggerScriptSource(
       
   431         WebCore::String(debuggerScriptJs.data(), debuggerScriptJs.length()));
       
   432 }
       
   433 
       
   434 void WebDevToolsAgentImpl::setInspectorFrontendProxyToInspectorController()
       
   435 {
       
   436     v8::HandleScope scope;
       
   437     ScriptState* state = ScriptState::forContext(
       
   438         v8::Local<v8::Context>::New(m_utilityContext));
       
   439     InspectorController* ic = inspectorController();
       
   440     ic->connectFrontend(ScriptObject(state, m_utilityContext->Global()));
       
   441 }
       
   442 
       
   443 void WebDevToolsAgentImpl::setApuAgentEnabled(bool enabled)
       
   444 {
       
   445     m_apuAgentEnabled = enabled;
       
   446     InspectorController* ic = m_webViewImpl->page()->inspectorController();
       
   447     if (enabled) {
       
   448         m_resourceTrackingWasEnabled = ic->resourceTrackingEnabled();
       
   449         ic->startTimelineProfiler();
       
   450         if (!m_resourceTrackingWasEnabled) {
       
   451             // TODO(knorton): Introduce some kind of agents dependency here so that
       
   452             // user could turn off resource tracking while apu agent is on.
       
   453             ic->enableResourceTracking(false, false);
       
   454         }
       
   455         m_debuggerAgentImpl->setAutoContinueOnException(true);
       
   456     } else {
       
   457       ic->stopTimelineProfiler();
       
   458       if (!m_resourceTrackingWasEnabled)
       
   459           ic->disableResourceTracking(false);
       
   460       m_resourceTrackingWasEnabled = false;
       
   461     }
       
   462     m_client->runtimeFeatureStateChanged(
       
   463         kApuAgentFeatureName,
       
   464         enabled);
       
   465 }
       
   466 
       
   467 // static
       
   468 v8::Handle<v8::Value> WebDevToolsAgentImpl::jsDispatchOnClient(const v8::Arguments& args)
       
   469 {
       
   470     v8::TryCatch exceptionCatcher;
       
   471     String message = WebCore::toWebCoreStringWithNullCheck(args[0]);
       
   472     if (message.isEmpty() || exceptionCatcher.HasCaught())
       
   473         return v8::Undefined();
       
   474 
       
   475     WebDevToolsAgentImpl* agent = static_cast<WebDevToolsAgentImpl*>(v8::External::Cast(*args.Data())->Value());
       
   476 
       
   477     if (!agent->m_apuAgentEnabled) {
       
   478         agent->m_toolsAgentDelegateStub->dispatchOnClient(message);
       
   479         return v8::Undefined();
       
   480     }
       
   481 
       
   482     String method = WebCore::toWebCoreStringWithNullCheck(args[1]);
       
   483     if (method.isEmpty() || exceptionCatcher.HasCaught())
       
   484         return v8::Undefined();
       
   485 
       
   486     if (method != "addRecordToTimeline" && method != "updateResource" && method != "addResource")
       
   487         return v8::Undefined();
       
   488 
       
   489     agent->m_apuAgentDelegateStub->dispatchToApu(message);
       
   490     return v8::Undefined();
       
   491 }
       
   492 
       
   493 WebCore::InspectorController* WebDevToolsAgentImpl::inspectorController()
       
   494 {
       
   495     if (Page* page = m_webViewImpl->page())
       
   496         return page->inspectorController();
       
   497     return 0;
       
   498 }
       
   499 
       
   500 
       
   501 //------- plugin resource load notifications ---------------
       
   502 void WebDevToolsAgentImpl::identifierForInitialRequest(
       
   503     unsigned long resourceId,
       
   504     WebFrame* frame,
       
   505     const WebURLRequest& request)
       
   506 {
       
   507     if (InspectorController* ic = inspectorController()) {
       
   508         WebFrameImpl* webFrameImpl = static_cast<WebFrameImpl*>(frame);
       
   509         FrameLoader* frameLoader = webFrameImpl->frame()->loader();
       
   510         DocumentLoader* loader = frameLoader->activeDocumentLoader();
       
   511         ic->identifierForInitialRequest(resourceId, loader, request.toResourceRequest());
       
   512     }
       
   513 }
       
   514 
       
   515 void WebDevToolsAgentImpl::willSendRequest(unsigned long resourceId, WebURLRequest& request)
       
   516 {
       
   517     if (InspectorController* ic = inspectorController())
       
   518         ic->willSendRequest(resourceId, request.toMutableResourceRequest(), ResourceResponse());
       
   519 }
       
   520 
       
   521 void WebDevToolsAgentImpl::didReceiveData(unsigned long resourceId, int length)
       
   522 {
       
   523     if (InspectorController* ic = inspectorController())
       
   524         ic->didReceiveContentLength(resourceId, length);
       
   525 }
       
   526 
       
   527 void WebDevToolsAgentImpl::didReceiveResponse(unsigned long resourceId, const WebURLResponse& response)
       
   528 {
       
   529     if (InspectorController* ic = inspectorController())
       
   530         ic->didReceiveResponse(resourceId, response.toResourceResponse());
       
   531 }
       
   532 
       
   533 void WebDevToolsAgentImpl::didFinishLoading(unsigned long resourceId)
       
   534 {
       
   535     if (InspectorController* ic = inspectorController())
       
   536         ic->didFinishLoading(resourceId);
       
   537 }
       
   538 
       
   539 void WebDevToolsAgentImpl::didFailLoading(unsigned long resourceId, const WebURLError& error)
       
   540 {
       
   541     ResourceError resourceError;
       
   542     if (InspectorController* ic = inspectorController())
       
   543         ic->didFailLoading(resourceId, resourceError);
       
   544 }
       
   545 
       
   546 void WebDevToolsAgentImpl::inspectorDestroyed()
       
   547 {
       
   548     // Our lifetime is bound to the WebViewImpl.
       
   549 }
       
   550 
       
   551 void WebDevToolsAgentImpl::openInspectorFrontend(InspectorController*)
       
   552 {
       
   553 }
       
   554 
       
   555 void WebDevToolsAgentImpl::highlight(Node* node)
       
   556 {
       
   557     // InspectorController does the actuall tracking of the highlighted node
       
   558     // and the drawing of the highlight. Here we just make sure to invalidate
       
   559     // the rects of the old and new nodes.
       
   560     hideHighlight();
       
   561 }
       
   562 
       
   563 void WebDevToolsAgentImpl::hideHighlight()
       
   564 {
       
   565     // FIXME: able to invalidate a smaller rect.
       
   566     // FIXME: Is it important to just invalidate the rect of the node region
       
   567     // given that this is not on a critical codepath?  In order to do so, we'd
       
   568     // have to take scrolling into account.
       
   569     const WebSize& size = m_webViewImpl->size();
       
   570     WebRect damagedRect(0, 0, size.width, size.height);
       
   571     if (m_webViewImpl->client())
       
   572         m_webViewImpl->client()->didInvalidateRect(damagedRect);
       
   573 }
       
   574 
       
   575 void WebDevToolsAgentImpl::populateSetting(const String& key, String* value)
       
   576 {
       
   577     WebString string;
       
   578     m_webViewImpl->inspectorSetting(key, &string);
       
   579     *value = string;
       
   580 }
       
   581 
       
   582 void WebDevToolsAgentImpl::storeSetting(const String& key, const String& value)
       
   583 {
       
   584     m_webViewImpl->setInspectorSetting(key, value);
       
   585 }
       
   586 
       
   587 bool WebDevToolsAgentImpl::sendMessageToFrontend(const WebCore::String& message)
       
   588 {
       
   589     WebDevToolsAgentImpl* devToolsAgent = static_cast<WebDevToolsAgentImpl*>(m_webViewImpl->devToolsAgent());
       
   590     if (!devToolsAgent)
       
   591         return false;
       
   592 
       
   593     if (devToolsAgent->m_apuAgentEnabled && devToolsAgent->m_apuAgentDelegateStub) {
       
   594         devToolsAgent->m_apuAgentDelegateStub->dispatchToApu(message);
       
   595         return true;
       
   596     }
       
   597 
       
   598     WebVector<WebString> arguments(size_t(1));
       
   599     arguments[0] = message;
       
   600     WebDevToolsMessageData data;
       
   601     data.className = "ToolsAgentDelegate";
       
   602     data.methodName = "dispatchOnClient";
       
   603     data.arguments.swap(arguments);
       
   604     devToolsAgent->sendRpcMessage(data);
       
   605     return true;
       
   606 }
       
   607 
       
   608 void WebDevToolsAgentImpl::resourceTrackingWasEnabled()
       
   609 {
       
   610     m_client->runtimeFeatureStateChanged(kResourceTrackingFeatureName, true);
       
   611 }
       
   612 
       
   613 void WebDevToolsAgentImpl::resourceTrackingWasDisabled()
       
   614 {
       
   615     m_client->runtimeFeatureStateChanged(kResourceTrackingFeatureName, false);
       
   616 }
       
   617 
       
   618 void WebDevToolsAgentImpl::timelineProfilerWasStarted()
       
   619 {
       
   620     m_client->runtimeFeatureStateChanged(kTimelineFeatureName, true);
       
   621 }
       
   622 
       
   623 void WebDevToolsAgentImpl::timelineProfilerWasStopped()
       
   624 {
       
   625     m_client->runtimeFeatureStateChanged(kTimelineFeatureName, false);
       
   626 }
       
   627 
       
   628 void WebDevToolsAgentImpl::evaluateInWebInspector(long callId, const WebString& script)
       
   629 {
       
   630     InspectorController* ic = inspectorController();
       
   631     ic->evaluateForTestInFrontend(callId, script);
       
   632 }
       
   633 
       
   634 void WebDevToolsAgentImpl::setTimelineProfilingEnabled(bool enabled)
       
   635 {
       
   636     InspectorController* ic = inspectorController();
       
   637     if (enabled)
       
   638         ic->startTimelineProfiler();
       
   639     else
       
   640         ic->stopTimelineProfiler();
       
   641 }
       
   642 
       
   643 void WebDevToolsAgent::executeDebuggerCommand(const WebString& command, int callerId)
       
   644 {
       
   645     DebuggerAgentManager::executeDebuggerCommand(command, callerId);
       
   646 }
       
   647 
       
   648 void WebDevToolsAgent::debuggerPauseScript()
       
   649 {
       
   650     DebuggerAgentManager::pauseScript();
       
   651 }
       
   652 
       
   653 void WebDevToolsAgent::setMessageLoopDispatchHandler(MessageLoopDispatchHandler handler)
       
   654 {
       
   655     DebuggerAgentManager::setMessageLoopDispatchHandler(handler);
       
   656 }
       
   657 
       
   658 bool WebDevToolsAgent::dispatchMessageFromFrontendOnIOThread(WebDevToolsMessageTransport* transport, const WebDevToolsMessageData& data)
       
   659 {
       
   660     IORPCDelegate delegate(transport);
       
   661     ProfilerAgentDelegateStub stub(&delegate);
       
   662     ProfilerAgentImpl agent(&stub);
       
   663     return ProfilerAgentDispatch::dispatch(&agent, data);
       
   664 }
       
   665 
       
   666 } // namespace WebKit