1 /* 2 * Copyright (C) 2010-2011 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 "InspectorBackendDispatcher.h" 35 #include "InspectorFrontend.h" 36 #include "InspectorProtocolVersion.h" 37 #include "RuntimeEnabledFeatures.h" 38 #include "WebDataSource.h" 39 #include "WebDevToolsAgentClient.h" 40 #include "WebFrameImpl.h" 41 #include "WebInputEventConversion.h" 42 #include "WebMemoryUsageInfo.h" 43 #include "WebSettings.h" 44 #include "WebViewClient.h" 45 #include "WebViewImpl.h" 46 #include "bindings/v8/PageScriptDebugServer.h" 47 #include "bindings/v8/ScriptController.h" 48 #include "bindings/v8/V8Binding.h" 49 #include "bindings/v8/V8Utilities.h" 50 #include "core/dom/ExceptionCode.h" 51 #include "core/fetch/MemoryCache.h" 52 #include "core/frame/Frame.h" 53 #include "core/frame/FrameView.h" 54 #include "core/inspector/InjectedScriptHost.h" 55 #include "core/inspector/InspectorController.h" 56 #include "core/page/Page.h" 57 #include "core/page/PageGroup.h" 58 #include "core/rendering/RenderView.h" 59 #include "platform/JSONValues.h" 60 #include "platform/graphics/GraphicsContext.h" 61 #include "platform/network/ResourceError.h" 62 #include "platform/network/ResourceRequest.h" 63 #include "platform/network/ResourceResponse.h" 64 #include "public/platform/Platform.h" 65 #include "public/platform/WebRect.h" 66 #include "public/platform/WebString.h" 67 #include "public/platform/WebURL.h" 68 #include "public/platform/WebURLError.h" 69 #include "public/platform/WebURLRequest.h" 70 #include "public/platform/WebURLResponse.h" 71 #include "wtf/CurrentTime.h" 72 #include "wtf/MathExtras.h" 73 #include "wtf/Noncopyable.h" 74 #include "wtf/text/WTFString.h" 75 76 using namespace WebCore; 77 using namespace std; 78 79 namespace OverlayZOrders { 80 // Use 99 as a big z-order number so that highlight is above other overlays. 81 static const int highlight = 99; 82 } 83 84 namespace blink { 85 86 class ClientMessageLoopAdapter : public PageScriptDebugServer::ClientMessageLoop { 87 public: 88 static void ensureClientMessageLoopCreated(WebDevToolsAgentClient* client) 89 { 90 if (s_instance) 91 return; 92 OwnPtr<ClientMessageLoopAdapter> instance = adoptPtr(new ClientMessageLoopAdapter(adoptPtr(client->createClientMessageLoop()))); 93 s_instance = instance.get(); 94 PageScriptDebugServer::shared().setClientMessageLoop(instance.release()); 95 } 96 97 static void inspectedViewClosed(WebViewImpl* view) 98 { 99 if (s_instance) 100 s_instance->m_frozenViews.remove(view); 101 } 102 103 static void didNavigate() 104 { 105 // Release render thread if necessary. 106 if (s_instance && s_instance->m_running) 107 PageScriptDebugServer::shared().continueProgram(); 108 } 109 110 private: 111 ClientMessageLoopAdapter(PassOwnPtr<blink::WebDevToolsAgentClient::WebKitClientMessageLoop> messageLoop) 112 : m_running(false) 113 , m_messageLoop(messageLoop) { } 114 115 116 virtual void run(Page* page) 117 { 118 if (m_running) 119 return; 120 m_running = true; 121 122 Vector<WebViewImpl*> views; 123 124 // 1. Disable input events. 125 HashSet<Page*>::const_iterator end = page->group().pages().end(); 126 for (HashSet<Page*>::const_iterator it = page->group().pages().begin(); it != end; ++it) { 127 WebViewImpl* view = WebViewImpl::fromPage(*it); 128 if (!view) 129 continue; 130 m_frozenViews.add(view); 131 views.append(view); 132 view->setIgnoreInputEvents(true); 133 } 134 135 // 2. Disable active objects 136 WebView::willEnterModalLoop(); 137 138 // 3. Process messages until quitNow is called. 139 m_messageLoop->run(); 140 141 // 4. Resume active objects 142 WebView::didExitModalLoop(); 143 144 // 5. Resume input events. 145 for (Vector<WebViewImpl*>::iterator it = views.begin(); it != views.end(); ++it) { 146 if (m_frozenViews.contains(*it)) { 147 // The view was not closed during the dispatch. 148 (*it)->setIgnoreInputEvents(false); 149 } 150 } 151 152 // 6. All views have been resumed, clear the set. 153 m_frozenViews.clear(); 154 155 m_running = false; 156 } 157 158 virtual void quitNow() 159 { 160 m_messageLoop->quitNow(); 161 } 162 163 bool m_running; 164 OwnPtr<blink::WebDevToolsAgentClient::WebKitClientMessageLoop> m_messageLoop; 165 typedef HashSet<WebViewImpl*> FrozenViewsSet; 166 FrozenViewsSet m_frozenViews; 167 // FIXME: The ownership model for s_instance is somewhat complicated. Can we make this simpler? 168 static ClientMessageLoopAdapter* s_instance; 169 }; 170 171 ClientMessageLoopAdapter* ClientMessageLoopAdapter::s_instance = 0; 172 173 class DebuggerTask : public PageScriptDebugServer::Task { 174 public: 175 DebuggerTask(PassOwnPtr<WebDevToolsAgent::MessageDescriptor> descriptor) 176 : m_descriptor(descriptor) 177 { 178 } 179 180 virtual ~DebuggerTask() { } 181 virtual void run() 182 { 183 if (WebDevToolsAgent* webagent = m_descriptor->agent()) 184 webagent->dispatchOnInspectorBackend(m_descriptor->message()); 185 } 186 187 private: 188 OwnPtr<WebDevToolsAgent::MessageDescriptor> m_descriptor; 189 }; 190 191 WebDevToolsAgentImpl::WebDevToolsAgentImpl( 192 WebViewImpl* webViewImpl, 193 WebDevToolsAgentClient* client) 194 : m_hostId(client->hostIdentifier()) 195 , m_client(client) 196 , m_webViewImpl(webViewImpl) 197 , m_attached(false) 198 , m_generatingEvent(false) 199 , m_deviceMetricsEnabled(false) 200 , m_emulateViewportEnabled(false) 201 , m_originalViewportEnabled(false) 202 , m_isOverlayScrollbarsEnabled(false) 203 { 204 ASSERT(m_hostId > 0); 205 ClientMessageLoopAdapter::ensureClientMessageLoopCreated(m_client); 206 } 207 208 WebDevToolsAgentImpl::~WebDevToolsAgentImpl() 209 { 210 ClientMessageLoopAdapter::inspectedViewClosed(m_webViewImpl); 211 if (m_attached) 212 blink::Platform::current()->currentThread()->removeTaskObserver(this); 213 } 214 215 void WebDevToolsAgentImpl::attach() 216 { 217 if (m_attached) 218 return; 219 220 inspectorController()->connectFrontend(this); 221 inspectorController()->webViewResized(m_webViewImpl->size()); 222 blink::Platform::current()->currentThread()->addTaskObserver(this); 223 m_attached = true; 224 } 225 226 void WebDevToolsAgentImpl::reattach(const WebString& savedState) 227 { 228 if (m_attached) 229 return; 230 231 inspectorController()->reuseFrontend(this, savedState); 232 blink::Platform::current()->currentThread()->addTaskObserver(this); 233 m_attached = true; 234 } 235 236 void WebDevToolsAgentImpl::detach() 237 { 238 blink::Platform::current()->currentThread()->removeTaskObserver(this); 239 240 // Prevent controller from sending messages to the frontend. 241 InspectorController* ic = inspectorController(); 242 ic->disconnectFrontend(); 243 ic->hideHighlight(); 244 m_attached = false; 245 } 246 247 void WebDevToolsAgentImpl::didNavigate() 248 { 249 ClientMessageLoopAdapter::didNavigate(); 250 } 251 252 void WebDevToolsAgentImpl::didBeginFrame(int frameId) 253 { 254 if (InspectorController* ic = inspectorController()) 255 ic->didBeginFrame(frameId); 256 } 257 258 void WebDevToolsAgentImpl::didCancelFrame() 259 { 260 if (InspectorController* ic = inspectorController()) 261 ic->didCancelFrame(); 262 } 263 264 void WebDevToolsAgentImpl::willComposite() 265 { 266 if (InspectorController* ic = inspectorController()) 267 ic->willComposite(); 268 } 269 270 void WebDevToolsAgentImpl::didComposite() 271 { 272 if (InspectorController* ic = inspectorController()) 273 ic->didComposite(); 274 } 275 276 void WebDevToolsAgentImpl::didCreateScriptContext(WebFrameImpl* webframe, int worldId) 277 { 278 // Skip non main world contexts. 279 if (worldId) 280 return; 281 if (WebCore::Frame* frame = webframe->frame()) 282 frame->script().setContextDebugId(m_hostId); 283 } 284 285 void WebDevToolsAgentImpl::webViewResized(const WebSize& size) 286 { 287 if (InspectorController* ic = inspectorController()) 288 ic->webViewResized(IntSize()); 289 } 290 291 bool WebDevToolsAgentImpl::handleInputEvent(WebCore::Page* page, const WebInputEvent& inputEvent) 292 { 293 if (!m_attached && !m_generatingEvent) 294 return false; 295 296 InspectorController* ic = inspectorController(); 297 if (!ic) 298 return false; 299 300 if (WebInputEvent::isGestureEventType(inputEvent.type) && inputEvent.type == WebInputEvent::GestureTap) { 301 // Only let GestureTab in (we only need it and we know PlatformGestureEventBuilder supports it). 302 PlatformGestureEvent gestureEvent = PlatformGestureEventBuilder(page->mainFrame()->view(), *static_cast<const WebGestureEvent*>(&inputEvent)); 303 return ic->handleGestureEvent(page->mainFrame(), gestureEvent); 304 } 305 if (WebInputEvent::isMouseEventType(inputEvent.type) && inputEvent.type != WebInputEvent::MouseEnter) { 306 // PlatformMouseEventBuilder does not work with MouseEnter type, so we filter it out manually. 307 PlatformMouseEvent mouseEvent = PlatformMouseEventBuilder(page->mainFrame()->view(), *static_cast<const WebMouseEvent*>(&inputEvent)); 308 return ic->handleMouseEvent(page->mainFrame(), mouseEvent); 309 } 310 if (WebInputEvent::isTouchEventType(inputEvent.type)) { 311 PlatformTouchEvent touchEvent = PlatformTouchEventBuilder(page->mainFrame()->view(), *static_cast<const WebTouchEvent*>(&inputEvent)); 312 return ic->handleTouchEvent(page->mainFrame(), touchEvent); 313 } 314 if (WebInputEvent::isKeyboardEventType(inputEvent.type)) { 315 PlatformKeyboardEvent keyboardEvent = PlatformKeyboardEventBuilder(*static_cast<const WebKeyboardEvent*>(&inputEvent)); 316 return ic->handleKeyboardEvent(page->mainFrame(), keyboardEvent); 317 } 318 return false; 319 } 320 321 void WebDevToolsAgentImpl::overrideDeviceMetrics(int width, int height, float deviceScaleFactor, bool emulateViewport, bool fitWindow) 322 { 323 if (!width && !height) { 324 if (m_deviceMetricsEnabled) { 325 m_deviceMetricsEnabled = false; 326 m_webViewImpl->setBackgroundColorOverride(Color::transparent); 327 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(m_isOverlayScrollbarsEnabled); 328 disableViewportEmulation(); 329 m_client->disableDeviceEmulation(); 330 } 331 } else { 332 if (!m_deviceMetricsEnabled) { 333 m_deviceMetricsEnabled = true; 334 m_webViewImpl->setBackgroundColorOverride(Color::darkGray); 335 m_isOverlayScrollbarsEnabled = RuntimeEnabledFeatures::overlayScrollbarsEnabled(); 336 RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(true); 337 } 338 if (emulateViewport) 339 enableViewportEmulation(); 340 else 341 disableViewportEmulation(); 342 m_client->enableDeviceEmulation(IntRect(10, 10, width, height), IntRect(0, 0, width, height), deviceScaleFactor, fitWindow); 343 } 344 } 345 346 void WebDevToolsAgentImpl::enableViewportEmulation() 347 { 348 if (m_emulateViewportEnabled) 349 return; 350 m_emulateViewportEnabled = true; 351 m_originalViewportEnabled = RuntimeEnabledFeatures::cssViewportEnabled(); 352 RuntimeEnabledFeatures::setCSSViewportEnabled(true); 353 m_webViewImpl->settings()->setViewportEnabled(true); 354 m_webViewImpl->settings()->setViewportMetaEnabled(true); 355 m_webViewImpl->setIgnoreViewportTagScaleLimits(true); 356 m_webViewImpl->setPageScaleFactorLimits(-1, -1); 357 m_webViewImpl->setZoomFactorOverride(1); 358 } 359 360 void WebDevToolsAgentImpl::disableViewportEmulation() 361 { 362 if (!m_emulateViewportEnabled) 363 return; 364 RuntimeEnabledFeatures::setCSSViewportEnabled(m_originalViewportEnabled); 365 m_webViewImpl->settings()->setViewportEnabled(false); 366 m_webViewImpl->settings()->setViewportMetaEnabled(false); 367 m_webViewImpl->setIgnoreViewportTagScaleLimits(false); 368 m_webViewImpl->setPageScaleFactorLimits(1, 1); 369 m_webViewImpl->setZoomFactorOverride(0); 370 m_emulateViewportEnabled = false; 371 } 372 373 void WebDevToolsAgentImpl::getAllocatedObjects(HashSet<const void*>& set) 374 { 375 class CountingVisitor : public WebDevToolsAgentClient::AllocatedObjectVisitor { 376 public: 377 CountingVisitor() : m_totalObjectsCount(0) 378 { 379 } 380 381 virtual bool visitObject(const void* ptr) 382 { 383 ++m_totalObjectsCount; 384 return true; 385 } 386 size_t totalObjectsCount() const 387 { 388 return m_totalObjectsCount; 389 } 390 391 private: 392 size_t m_totalObjectsCount; 393 }; 394 395 CountingVisitor counter; 396 m_client->visitAllocatedObjects(&counter); 397 398 class PointerCollector : public WebDevToolsAgentClient::AllocatedObjectVisitor { 399 public: 400 explicit PointerCollector(size_t maxObjectsCount) 401 : m_maxObjectsCount(maxObjectsCount) 402 , m_index(0) 403 , m_success(true) 404 , m_pointers(new const void*[maxObjectsCount]) 405 { 406 } 407 virtual ~PointerCollector() 408 { 409 delete[] m_pointers; 410 } 411 virtual bool visitObject(const void* ptr) 412 { 413 if (m_index == m_maxObjectsCount) { 414 m_success = false; 415 return false; 416 } 417 m_pointers[m_index++] = ptr; 418 return true; 419 } 420 421 bool success() const { return m_success; } 422 423 void copyTo(HashSet<const void*>& set) 424 { 425 for (size_t i = 0; i < m_index; i++) 426 set.add(m_pointers[i]); 427 } 428 429 private: 430 const size_t m_maxObjectsCount; 431 size_t m_index; 432 bool m_success; 433 const void** m_pointers; 434 }; 435 436 // Double size to allow room for all objects that may have been allocated 437 // since we counted them. 438 size_t estimatedMaxObjectsCount = counter.totalObjectsCount() * 2; 439 while (true) { 440 PointerCollector collector(estimatedMaxObjectsCount); 441 m_client->visitAllocatedObjects(&collector); 442 if (collector.success()) { 443 collector.copyTo(set); 444 break; 445 } 446 estimatedMaxObjectsCount *= 2; 447 } 448 } 449 450 void WebDevToolsAgentImpl::dumpUncountedAllocatedObjects(const HashMap<const void*, size_t>& map) 451 { 452 class InstrumentedObjectSizeProvider : public WebDevToolsAgentClient::InstrumentedObjectSizeProvider { 453 public: 454 InstrumentedObjectSizeProvider(const HashMap<const void*, size_t>& map) : m_map(map) { } 455 virtual size_t objectSize(const void* ptr) const 456 { 457 HashMap<const void*, size_t>::const_iterator i = m_map.find(ptr); 458 return i == m_map.end() ? 0 : i->value; 459 } 460 461 private: 462 const HashMap<const void*, size_t>& m_map; 463 }; 464 465 InstrumentedObjectSizeProvider provider(map); 466 m_client->dumpUncountedAllocatedObjects(&provider); 467 } 468 469 void WebDevToolsAgentImpl::setTraceEventCallback(TraceEventCallback callback) 470 { 471 m_client->setTraceEventCallback(callback); 472 } 473 474 void WebDevToolsAgentImpl::startGPUEventsRecording() 475 { 476 m_client->startGPUEventsRecording(); 477 } 478 479 void WebDevToolsAgentImpl::stopGPUEventsRecording() 480 { 481 m_client->stopGPUEventsRecording(); 482 } 483 484 void WebDevToolsAgentImpl::processGPUEvent(double timestamp, int phase, bool foreign) 485 { 486 if (InspectorController* ic = inspectorController()) 487 ic->processGPUEvent(timestamp, phase, foreign, 0); 488 } 489 490 void WebDevToolsAgentImpl::processGPUEvent(const GPUEvent& event) 491 { 492 if (InspectorController* ic = inspectorController()) 493 ic->processGPUEvent(event.timestamp, event.phase, event.foreign, event.usedGPUMemoryBytes); 494 } 495 496 void WebDevToolsAgentImpl::dispatchKeyEvent(const PlatformKeyboardEvent& event) 497 { 498 m_generatingEvent = true; 499 WebKeyboardEvent webEvent = WebKeyboardEventBuilder(event); 500 if (!webEvent.keyIdentifier[0] && webEvent.type != WebInputEvent::Char) 501 webEvent.setKeyIdentifierFromWindowsKeyCode(); 502 m_webViewImpl->handleInputEvent(webEvent); 503 m_generatingEvent = false; 504 } 505 506 void WebDevToolsAgentImpl::dispatchMouseEvent(const PlatformMouseEvent& event) 507 { 508 m_generatingEvent = true; 509 WebMouseEvent webEvent = WebMouseEventBuilder(m_webViewImpl->mainFrameImpl()->frameView(), event); 510 m_webViewImpl->handleInputEvent(webEvent); 511 m_generatingEvent = false; 512 } 513 514 void WebDevToolsAgentImpl::dispatchOnInspectorBackend(const WebString& message) 515 { 516 inspectorController()->dispatchMessageFromFrontend(message); 517 } 518 519 void WebDevToolsAgentImpl::inspectElementAt(const WebPoint& point) 520 { 521 m_webViewImpl->inspectElementAt(point); 522 } 523 524 InspectorController* WebDevToolsAgentImpl::inspectorController() 525 { 526 if (Page* page = m_webViewImpl->page()) 527 return &page->inspectorController(); 528 return 0; 529 } 530 531 Frame* WebDevToolsAgentImpl::mainFrame() 532 { 533 if (Page* page = m_webViewImpl->page()) 534 return page->mainFrame(); 535 return 0; 536 } 537 538 // WebPageOverlay 539 void WebDevToolsAgentImpl::paintPageOverlay(WebCanvas* canvas) 540 { 541 InspectorController* ic = inspectorController(); 542 if (ic) { 543 GraphicsContext context(canvas); 544 context.setCertainlyOpaque(false); 545 ic->drawHighlight(context); 546 } 547 } 548 549 void WebDevToolsAgentImpl::highlight() 550 { 551 m_webViewImpl->addPageOverlay(this, OverlayZOrders::highlight); 552 } 553 554 void WebDevToolsAgentImpl::hideHighlight() 555 { 556 m_webViewImpl->removePageOverlay(this); 557 } 558 559 bool WebDevToolsAgentImpl::sendMessageToFrontend(const String& message) 560 { 561 WebDevToolsAgentImpl* devToolsAgent = static_cast<WebDevToolsAgentImpl*>(m_webViewImpl->devToolsAgent()); 562 if (!devToolsAgent) 563 return false; 564 m_client->sendMessageToInspectorFrontend(message); 565 return true; 566 } 567 568 void WebDevToolsAgentImpl::updateInspectorStateCookie(const String& state) 569 { 570 m_client->saveAgentRuntimeState(state); 571 } 572 573 void WebDevToolsAgentImpl::clearBrowserCache() 574 { 575 m_client->clearBrowserCache(); 576 } 577 578 void WebDevToolsAgentImpl::clearBrowserCookies() 579 { 580 m_client->clearBrowserCookies(); 581 } 582 583 void WebDevToolsAgentImpl::setProcessId(long processId) 584 { 585 inspectorController()->setProcessId(processId); 586 } 587 588 void WebDevToolsAgentImpl::setLayerTreeId(int layerTreeId) 589 { 590 inspectorController()->setLayerTreeId(layerTreeId); 591 } 592 593 void WebDevToolsAgentImpl::evaluateInWebInspector(long callId, const WebString& script) 594 { 595 InspectorController* ic = inspectorController(); 596 ic->evaluateForTestInFrontend(callId, script); 597 } 598 599 void WebDevToolsAgentImpl::willProcessTask() 600 { 601 if (InspectorController* ic = inspectorController()) 602 ic->willProcessTask(); 603 } 604 605 void WebDevToolsAgentImpl::didProcessTask() 606 { 607 if (InspectorController* ic = inspectorController()) 608 ic->didProcessTask(); 609 } 610 611 WebString WebDevToolsAgent::inspectorProtocolVersion() 612 { 613 return WebCore::inspectorProtocolVersion(); 614 } 615 616 bool WebDevToolsAgent::supportsInspectorProtocolVersion(const WebString& version) 617 { 618 return WebCore::supportsInspectorProtocolVersion(version); 619 } 620 621 void WebDevToolsAgent::interruptAndDispatch(MessageDescriptor* rawDescriptor) 622 { 623 // rawDescriptor can't be a PassOwnPtr because interruptAndDispatch is a WebKit API function. 624 OwnPtr<MessageDescriptor> descriptor = adoptPtr(rawDescriptor); 625 OwnPtr<DebuggerTask> task = adoptPtr(new DebuggerTask(descriptor.release())); 626 PageScriptDebugServer::interruptAndRun(task.release(), v8::Isolate::GetCurrent()); 627 } 628 629 bool WebDevToolsAgent::shouldInterruptForMessage(const WebString& message) 630 { 631 String commandName; 632 if (!InspectorBackendDispatcher::getCommandName(message, &commandName)) 633 return false; 634 return commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_pauseCmd) 635 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_setBreakpointCmd) 636 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_setBreakpointByUrlCmd) 637 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_removeBreakpointCmd) 638 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kDebugger_setBreakpointsActiveCmd) 639 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kProfiler_startCmd) 640 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kProfiler_stopCmd) 641 || commandName == InspectorBackendDispatcher::commandName(InspectorBackendDispatcher::kHeapProfiler_getHeapSnapshotCmd); 642 } 643 644 void WebDevToolsAgent::processPendingMessages() 645 { 646 PageScriptDebugServer::shared().runPendingTasks(); 647 } 648 649 } // namespace blink 650