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 "core/inspector/TimelineRecordFactory.h" 33 34#include "bindings/core/v8/ScriptCallStackFactory.h" 35#include "core/events/Event.h" 36#include "core/inspector/ScriptCallStack.h" 37#include "platform/geometry/FloatQuad.h" 38#include "platform/geometry/LayoutRect.h" 39#include "platform/network/ResourceRequest.h" 40#include "platform/network/ResourceResponse.h" 41#include "wtf/CurrentTime.h" 42 43namespace blink { 44 45using TypeBuilder::Timeline::TimelineEvent; 46 47PassRefPtr<TimelineEvent> TimelineRecordFactory::createGenericRecord(double startTime, int maxCallStackDepth, const String& type, PassRefPtr<JSONObject> data) 48{ 49 ASSERT(data.get()); 50 RefPtr<TimelineEvent> record = TimelineEvent::create() 51 .setType(type) 52 .setData(data) 53 .setStartTime(startTime); 54 if (maxCallStackDepth) { 55 RefPtrWillBeRawPtr<ScriptCallStack> stackTrace = createScriptCallStack(maxCallStackDepth, true); 56 if (stackTrace && stackTrace->size()) 57 record->setStackTrace(stackTrace->buildInspectorArray()); 58 } 59 return record.release(); 60} 61 62PassRefPtr<TimelineEvent> TimelineRecordFactory::createBackgroundRecord(double startTime, const String& threadName, const String& type, PassRefPtr<JSONObject> data) 63{ 64 ASSERT(data.get()); 65 RefPtr<TimelineEvent> record = TimelineEvent::create() 66 .setType(type) 67 .setData(data) 68 .setStartTime(startTime); 69 record->setThread(threadName); 70 return record.release(); 71} 72 73PassRefPtr<JSONObject> TimelineRecordFactory::createGCEventData(size_t usedHeapSizeDelta) 74{ 75 RefPtr<JSONObject> data = JSONObject::create(); 76 data->setNumber("usedHeapSizeDelta", usedHeapSizeDelta); 77 return data.release(); 78} 79 80PassRefPtr<JSONObject> TimelineRecordFactory::createFunctionCallData(int scriptId, const String& scriptName, int scriptLine) 81{ 82 RefPtr<JSONObject> data = JSONObject::create(); 83 data->setString("scriptId", String::number(scriptId)); 84 data->setString("scriptName", scriptName); 85 data->setNumber("scriptLine", scriptLine); 86 return data.release(); 87} 88 89PassRefPtr<JSONObject> TimelineRecordFactory::createEventDispatchData(const Event& event) 90{ 91 RefPtr<JSONObject> data = JSONObject::create(); 92 data->setString("type", event.type().string()); 93 return data.release(); 94} 95 96PassRefPtr<JSONObject> TimelineRecordFactory::createGenericTimerData(int timerId) 97{ 98 RefPtr<JSONObject> data = JSONObject::create(); 99 data->setNumber("timerId", timerId); 100 return data.release(); 101} 102 103PassRefPtr<JSONObject> TimelineRecordFactory::createTimerInstallData(int timerId, int timeout, bool singleShot) 104{ 105 RefPtr<JSONObject> data = JSONObject::create(); 106 data->setNumber("timerId", timerId); 107 data->setNumber("timeout", timeout); 108 data->setBoolean("singleShot", singleShot); 109 return data.release(); 110} 111 112PassRefPtr<JSONObject> TimelineRecordFactory::createXHRReadyStateChangeData(const String& url, int readyState) 113{ 114 RefPtr<JSONObject> data = JSONObject::create(); 115 data->setString("url", url); 116 data->setNumber("readyState", readyState); 117 return data.release(); 118} 119 120PassRefPtr<JSONObject> TimelineRecordFactory::createXHRLoadData(const String& url) 121{ 122 RefPtr<JSONObject> data = JSONObject::create(); 123 data->setString("url", url); 124 return data.release(); 125} 126 127PassRefPtr<JSONObject> TimelineRecordFactory::createEvaluateScriptData(const String& url, double lineNumber) 128{ 129 RefPtr<JSONObject> data = JSONObject::create(); 130 data->setString("url", url); 131 data->setNumber("lineNumber", lineNumber); 132 return data.release(); 133} 134 135PassRefPtr<JSONObject> TimelineRecordFactory::createConsoleTimeData(const String& message) 136{ 137 RefPtr<JSONObject> data = JSONObject::create(); 138 data->setString("message", message); 139 return data.release(); 140} 141 142PassRefPtr<JSONObject> TimelineRecordFactory::createTimeStampData(const String& message) 143{ 144 RefPtr<JSONObject> data = JSONObject::create(); 145 data->setString("message", message); 146 return data.release(); 147} 148 149PassRefPtr<JSONObject> TimelineRecordFactory::createResourceSendRequestData(const String& requestId, const ResourceRequest& request) 150{ 151 RefPtr<JSONObject> data = JSONObject::create(); 152 data->setString("requestId", requestId); 153 data->setString("url", request.url().string()); 154 data->setString("requestMethod", request.httpMethod()); 155 return data.release(); 156} 157 158PassRefPtr<JSONObject> TimelineRecordFactory::createResourceReceiveResponseData(const String& requestId, const ResourceResponse& response) 159{ 160 RefPtr<JSONObject> data = JSONObject::create(); 161 data->setString("requestId", requestId); 162 data->setNumber("statusCode", response.httpStatusCode()); 163 data->setString("mimeType", response.mimeType()); 164 return data.release(); 165} 166 167PassRefPtr<JSONObject> TimelineRecordFactory::createResourceFinishData(const String& requestId, bool didFail, double finishTime) 168{ 169 RefPtr<JSONObject> data = JSONObject::create(); 170 data->setString("requestId", requestId); 171 data->setBoolean("didFail", didFail); 172 if (finishTime) 173 data->setNumber("networkTime", finishTime); 174 return data.release(); 175} 176 177PassRefPtr<JSONObject> TimelineRecordFactory::createReceiveResourceData(const String& requestId, int length) 178{ 179 RefPtr<JSONObject> data = JSONObject::create(); 180 data->setString("requestId", requestId); 181 data->setNumber("encodedDataLength", length); 182 return data.release(); 183} 184 185PassRefPtr<JSONObject> TimelineRecordFactory::createLayoutData(unsigned dirtyObjects, unsigned totalObjects, bool partialLayout) 186{ 187 RefPtr<JSONObject> data = JSONObject::create(); 188 data->setNumber("dirtyObjects", dirtyObjects); 189 data->setNumber("totalObjects", totalObjects); 190 data->setBoolean("partialLayout", partialLayout); 191 return data.release(); 192} 193 194PassRefPtr<JSONObject> TimelineRecordFactory::createDecodeImageData(const String& imageType) 195{ 196 RefPtr<JSONObject> data = JSONObject::create(); 197 data->setString("imageType", imageType); 198 return data.release(); 199} 200 201PassRefPtr<JSONObject> TimelineRecordFactory::createResizeImageData(bool shouldCache) 202{ 203 RefPtr<JSONObject> data = JSONObject::create(); 204 data->setBoolean("cached", shouldCache); 205 return data.release(); 206} 207 208PassRefPtr<JSONObject> TimelineRecordFactory::createMarkData(bool isMainFrame) 209{ 210 RefPtr<JSONObject> data = JSONObject::create(); 211 data->setBoolean("isMainFrame", isMainFrame); 212 return data.release(); 213} 214 215PassRefPtr<JSONObject> TimelineRecordFactory::createParseHTMLData(unsigned startLine) 216{ 217 RefPtr<JSONObject> data = JSONObject::create(); 218 data->setNumber("startLine", startLine); 219 return data.release(); 220} 221 222PassRefPtr<JSONObject> TimelineRecordFactory::createAnimationFrameData(int callbackId) 223{ 224 RefPtr<JSONObject> data = JSONObject::create(); 225 data->setNumber("id", callbackId); 226 return data.release(); 227} 228 229PassRefPtr<JSONObject> TimelineRecordFactory::createGPUTaskData(bool foreign) 230{ 231 RefPtr<JSONObject> data = JSONObject::create(); 232 data->setBoolean("foreign", foreign); 233 return data.release(); 234} 235 236static PassRefPtr<JSONArray> createQuad(const FloatQuad& quad) 237{ 238 RefPtr<JSONArray> array = JSONArray::create(); 239 array->pushNumber(quad.p1().x()); 240 array->pushNumber(quad.p1().y()); 241 array->pushNumber(quad.p2().x()); 242 array->pushNumber(quad.p2().y()); 243 array->pushNumber(quad.p3().x()); 244 array->pushNumber(quad.p3().y()); 245 array->pushNumber(quad.p4().x()); 246 array->pushNumber(quad.p4().y()); 247 return array.release(); 248} 249 250PassRefPtr<JSONObject> TimelineRecordFactory::createNodeData(long long nodeId) 251{ 252 RefPtr<JSONObject> data = JSONObject::create(); 253 setNodeData(data.get(), nodeId); 254 return data.release(); 255} 256 257PassRefPtr<JSONObject> TimelineRecordFactory::createLayerData(long long rootNodeId) 258{ 259 return createNodeData(rootNodeId); 260} 261 262void TimelineRecordFactory::setLayerTreeData(JSONObject* data, PassRefPtr<JSONValue> layerTree) 263{ 264 data->setValue("layerTree", layerTree); 265} 266 267void TimelineRecordFactory::setNodeData(JSONObject* data, long long nodeId) 268{ 269 if (nodeId) 270 data->setNumber("backendNodeId", nodeId); 271} 272 273void TimelineRecordFactory::setLayerData(JSONObject* data, long long rootNodeId) 274{ 275 setNodeData(data, rootNodeId); 276} 277 278void TimelineRecordFactory::setPaintData(JSONObject* data, const FloatQuad& quad, long long layerRootNodeId, int graphicsLayerId) 279{ 280 setLayerData(data, layerRootNodeId); 281 data->setArray("clip", createQuad(quad)); 282 data->setNumber("layerId", graphicsLayerId); 283} 284 285PassRefPtr<JSONObject> TimelineRecordFactory::createFrameData(int frameId) 286{ 287 RefPtr<JSONObject> data = JSONObject::create(); 288 data->setNumber("id", frameId); 289 return data.release(); 290} 291 292void TimelineRecordFactory::setLayoutRoot(JSONObject* data, const FloatQuad& quad, long long rootNodeId) 293{ 294 data->setArray("root", createQuad(quad)); 295 if (rootNodeId) 296 data->setNumber("backendNodeId", rootNodeId); 297} 298 299void TimelineRecordFactory::setStyleRecalcDetails(JSONObject* data, unsigned elementCount) 300{ 301 data->setNumber("elementCount", elementCount); 302} 303 304void TimelineRecordFactory::setImageDetails(JSONObject* data, long long imageElementId, const String& url) 305{ 306 if (imageElementId) 307 data->setNumber("backendNodeId", imageElementId); 308 if (!url.isEmpty()) 309 data->setString("url", url); 310} 311 312PassRefPtr<JSONObject> TimelineRecordFactory::createEmbedderCallbackData(const String& callbackName) 313{ 314 RefPtr<JSONObject> data = JSONObject::create(); 315 data->setString("callbackName", callbackName); 316 return data.release(); 317} 318 319String TimelineRecordFactory::type(TypeBuilder::Timeline::TimelineEvent* event) 320{ 321 String type; 322 event->type(&type); 323 return type; 324} 325 326} // namespace blink 327 328