Home | History | Annotate | Download | only in inspector
      1 /*
      2 * Copyright (C) 2009 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 "InspectorTimelineAgent.h"
     33 
     34 #if ENABLE(INSPECTOR)
     35 
     36 #include "Event.h"
     37 #include "InspectorFrontend.h"
     38 #include "IntRect.h"
     39 #include "ResourceRequest.h"
     40 #include "ResourceResponse.h"
     41 #include "TimelineRecordFactory.h"
     42 
     43 #include <wtf/CurrentTime.h>
     44 
     45 namespace WebCore {
     46 
     47 InspectorTimelineAgent::InspectorTimelineAgent(InspectorFrontend* frontend)
     48     : m_frontend(frontend)
     49 {
     50     ASSERT(m_frontend);
     51 }
     52 
     53 InspectorTimelineAgent::~InspectorTimelineAgent()
     54 {
     55 }
     56 
     57 void InspectorTimelineAgent::willDispatchEvent(const Event& event)
     58 {
     59     pushCurrentRecord(TimelineRecordFactory::createEventDispatchData(m_frontend, event),
     60         EventDispatchTimelineRecordType);
     61 }
     62 
     63 void InspectorTimelineAgent::didDispatchEvent()
     64 {
     65     didCompleteCurrentRecord(EventDispatchTimelineRecordType);
     66 }
     67 
     68 void InspectorTimelineAgent::willLayout()
     69 {
     70     pushCurrentRecord(m_frontend->newScriptObject(), LayoutTimelineRecordType);
     71 }
     72 
     73 void InspectorTimelineAgent::didLayout()
     74 {
     75     didCompleteCurrentRecord(LayoutTimelineRecordType);
     76 }
     77 
     78 void InspectorTimelineAgent::willRecalculateStyle()
     79 {
     80     pushCurrentRecord(m_frontend->newScriptObject(), RecalculateStylesTimelineRecordType);
     81 }
     82 
     83 void InspectorTimelineAgent::didRecalculateStyle()
     84 {
     85     didCompleteCurrentRecord(RecalculateStylesTimelineRecordType);
     86 }
     87 
     88 void InspectorTimelineAgent::willPaint(const IntRect& rect)
     89 {
     90     pushCurrentRecord(TimelineRecordFactory::createPaintData(m_frontend, rect), PaintTimelineRecordType);
     91 }
     92 
     93 void InspectorTimelineAgent::didPaint()
     94 {
     95     didCompleteCurrentRecord(PaintTimelineRecordType);
     96 }
     97 
     98 void InspectorTimelineAgent::willWriteHTML(unsigned int length, unsigned int startLine)
     99 {
    100     pushCurrentRecord(TimelineRecordFactory::createParseHTMLData(m_frontend, length, startLine), ParseHTMLTimelineRecordType);
    101 }
    102 
    103 void InspectorTimelineAgent::didWriteHTML(unsigned int endLine)
    104 {
    105     if (!m_recordStack.isEmpty()) {
    106         TimelineRecordEntry entry = m_recordStack.last();
    107         entry.data.set("endLine", endLine);
    108         didCompleteCurrentRecord(ParseHTMLTimelineRecordType);
    109     }
    110 }
    111 
    112 void InspectorTimelineAgent::didInstallTimer(int timerId, int timeout, bool singleShot)
    113 {
    114     ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
    115     record.set("data", TimelineRecordFactory::createTimerInstallData(m_frontend, timerId, timeout, singleShot));
    116     addRecordToTimeline(record, TimerInstallTimelineRecordType);
    117 }
    118 
    119 void InspectorTimelineAgent::didRemoveTimer(int timerId)
    120 {
    121     ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
    122     record.set("data", TimelineRecordFactory::createGenericTimerData(m_frontend, timerId));
    123     addRecordToTimeline(record, TimerRemoveTimelineRecordType);
    124 }
    125 
    126 void InspectorTimelineAgent::willFireTimer(int timerId)
    127 {
    128     pushCurrentRecord(TimelineRecordFactory::createGenericTimerData(m_frontend, timerId), TimerFireTimelineRecordType);
    129 }
    130 
    131 void InspectorTimelineAgent::didFireTimer()
    132 {
    133     didCompleteCurrentRecord(TimerFireTimelineRecordType);
    134 }
    135 
    136 void InspectorTimelineAgent::willChangeXHRReadyState(const String& url, int readyState)
    137 {
    138     pushCurrentRecord(TimelineRecordFactory::createXHRReadyStateChangeData(m_frontend, url, readyState), XHRReadyStateChangeRecordType);
    139 }
    140 
    141 void InspectorTimelineAgent::didChangeXHRReadyState()
    142 {
    143     didCompleteCurrentRecord(XHRReadyStateChangeRecordType);
    144 }
    145 
    146 void InspectorTimelineAgent::willLoadXHR(const String& url)
    147 {
    148     pushCurrentRecord(TimelineRecordFactory::createXHRLoadData(m_frontend, url), XHRLoadRecordType);
    149 }
    150 
    151 void InspectorTimelineAgent::didLoadXHR()
    152 {
    153     didCompleteCurrentRecord(XHRLoadRecordType);
    154 }
    155 
    156 void InspectorTimelineAgent::willEvaluateScript(const String& url, int lineNumber)
    157 {
    158     pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(m_frontend, url, lineNumber), EvaluateScriptTimelineRecordType);
    159 }
    160 
    161 void InspectorTimelineAgent::didEvaluateScript()
    162 {
    163     didCompleteCurrentRecord(EvaluateScriptTimelineRecordType);
    164 }
    165 
    166 void InspectorTimelineAgent::willSendResourceRequest(unsigned long identifier, bool isMainResource,
    167     const ResourceRequest& request)
    168 {
    169     ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
    170     record.set("data", TimelineRecordFactory::createResourceSendRequestData(m_frontend, identifier, isMainResource, request));
    171     record.set("type", ResourceSendRequestTimelineRecordType);
    172     m_frontend->addRecordToTimeline(record);
    173 }
    174 
    175 void InspectorTimelineAgent::didReceiveResourceResponse(unsigned long identifier, const ResourceResponse& response)
    176 {
    177     ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
    178     record.set("data", TimelineRecordFactory::createResourceReceiveResponseData(m_frontend, identifier, response));
    179     record.set("type", ResourceReceiveResponseTimelineRecordType);
    180     m_frontend->addRecordToTimeline(record);
    181 }
    182 
    183 void InspectorTimelineAgent::didFinishLoadingResource(unsigned long identifier, bool didFail)
    184 {
    185     ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
    186     record.set("data", TimelineRecordFactory::createResourceFinishData(m_frontend, identifier, didFail));
    187     record.set("type", ResourceFinishTimelineRecordType);
    188     m_frontend->addRecordToTimeline(record);
    189 }
    190 
    191 void InspectorTimelineAgent::didMarkTimeline(const String& message)
    192 {
    193     ScriptObject record = TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds());
    194     record.set("data", TimelineRecordFactory::createMarkTimelineData(m_frontend, message));
    195     addRecordToTimeline(record, MarkTimelineRecordType);
    196 }
    197 
    198 void InspectorTimelineAgent::reset()
    199 {
    200     m_recordStack.clear();
    201 }
    202 
    203 void InspectorTimelineAgent::resetFrontendProxyObject(InspectorFrontend* frontend)
    204 {
    205     ASSERT(frontend);
    206     reset();
    207     m_frontend = frontend;
    208 }
    209 
    210 void InspectorTimelineAgent::addRecordToTimeline(ScriptObject record, TimelineRecordType type)
    211 {
    212     record.set("type", type);
    213     if (m_recordStack.isEmpty())
    214         m_frontend->addRecordToTimeline(record);
    215     else {
    216         TimelineRecordEntry parent = m_recordStack.last();
    217         parent.children.set(parent.children.length(), record);
    218     }
    219 }
    220 
    221 void InspectorTimelineAgent::didCompleteCurrentRecord(TimelineRecordType type)
    222 {
    223     // An empty stack could merely mean that the timeline agent was turned on in the middle of
    224     // an event.  Don't treat as an error.
    225     if (!m_recordStack.isEmpty()) {
    226         TimelineRecordEntry entry = m_recordStack.last();
    227         m_recordStack.removeLast();
    228         ASSERT(entry.type == type);
    229         entry.record.set("data", entry.data);
    230         entry.record.set("children", entry.children);
    231         entry.record.set("endTime", currentTimeInMilliseconds());
    232         addRecordToTimeline(entry.record, type);
    233     }
    234 }
    235 
    236 double InspectorTimelineAgent::currentTimeInMilliseconds()
    237 {
    238     return currentTime() * 1000.0;
    239 }
    240 
    241 void InspectorTimelineAgent::pushCurrentRecord(ScriptObject data, TimelineRecordType type)
    242 {
    243     m_recordStack.append(TimelineRecordEntry(TimelineRecordFactory::createGenericRecord(m_frontend, currentTimeInMilliseconds()), data, m_frontend->newScriptArray(), type));
    244 }
    245 
    246 } // namespace WebCore
    247 
    248 #endif // ENABLE(INSPECTOR)
    249