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/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 43 namespace WebCore { 44 45 using TypeBuilder::Timeline::TimelineEvent; 46 47 PassRefPtr<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 62 PassRefPtr<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 73 PassRefPtr<JSONObject> TimelineRecordFactory::createGCEventData(size_t usedHeapSizeDelta) 74 { 75 RefPtr<JSONObject> data = JSONObject::create(); 76 data->setNumber("usedHeapSizeDelta", usedHeapSizeDelta); 77 return data.release(); 78 } 79 80 PassRefPtr<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 89 PassRefPtr<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 96 PassRefPtr<JSONObject> TimelineRecordFactory::createGenericTimerData(int timerId) 97 { 98 RefPtr<JSONObject> data = JSONObject::create(); 99 data->setNumber("timerId", timerId); 100 return data.release(); 101 } 102 103 PassRefPtr<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 112 PassRefPtr<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 120 PassRefPtr<JSONObject> TimelineRecordFactory::createXHRLoadData(const String& url) 121 { 122 RefPtr<JSONObject> data = JSONObject::create(); 123 data->setString("url", url); 124 return data.release(); 125 } 126 127 PassRefPtr<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 135 PassRefPtr<JSONObject> TimelineRecordFactory::createConsoleTimeData(const String& message) 136 { 137 RefPtr<JSONObject> data = JSONObject::create(); 138 data->setString("message", message); 139 return data.release(); 140 } 141 142 PassRefPtr<JSONObject> TimelineRecordFactory::createTimeStampData(const String& message) 143 { 144 RefPtr<JSONObject> data = JSONObject::create(); 145 data->setString("message", message); 146 return data.release(); 147 } 148 149 PassRefPtr<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 158 PassRefPtr<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 167 PassRefPtr<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 177 PassRefPtr<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 185 PassRefPtr<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 194 PassRefPtr<JSONObject> TimelineRecordFactory::createDecodeImageData(const String& imageType) 195 { 196 RefPtr<JSONObject> data = JSONObject::create(); 197 data->setString("imageType", imageType); 198 return data.release(); 199 } 200 201 PassRefPtr<JSONObject> TimelineRecordFactory::createResizeImageData(bool shouldCache) 202 { 203 RefPtr<JSONObject> data = JSONObject::create(); 204 data->setBoolean("cached", shouldCache); 205 return data.release(); 206 } 207 208 PassRefPtr<JSONObject> TimelineRecordFactory::createMarkData(bool isMainFrame) 209 { 210 RefPtr<JSONObject> data = JSONObject::create(); 211 data->setBoolean("isMainFrame", isMainFrame); 212 return data.release(); 213 } 214 215 PassRefPtr<JSONObject> TimelineRecordFactory::createParseHTMLData(unsigned startLine) 216 { 217 RefPtr<JSONObject> data = JSONObject::create(); 218 data->setNumber("startLine", startLine); 219 return data.release(); 220 } 221 222 PassRefPtr<JSONObject> TimelineRecordFactory::createAnimationFrameData(int callbackId) 223 { 224 RefPtr<JSONObject> data = JSONObject::create(); 225 data->setNumber("id", callbackId); 226 return data.release(); 227 } 228 229 PassRefPtr<JSONObject> TimelineRecordFactory::createGPUTaskData(bool foreign) 230 { 231 RefPtr<JSONObject> data = JSONObject::create(); 232 data->setBoolean("foreign", foreign); 233 return data.release(); 234 } 235 236 static 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 250 PassRefPtr<JSONObject> TimelineRecordFactory::createNodeData(long long nodeId) 251 { 252 RefPtr<JSONObject> data = JSONObject::create(); 253 setNodeData(data.get(), nodeId); 254 return data.release(); 255 } 256 257 PassRefPtr<JSONObject> TimelineRecordFactory::createLayerData(long long rootNodeId) 258 { 259 return createNodeData(rootNodeId); 260 } 261 262 void TimelineRecordFactory::setLayerTreeData(JSONObject* data, PassRefPtr<JSONValue> layerTree) 263 { 264 data->setValue("layerTree", layerTree); 265 } 266 267 void TimelineRecordFactory::setNodeData(JSONObject* data, long long nodeId) 268 { 269 if (nodeId) 270 data->setNumber("backendNodeId", nodeId); 271 } 272 273 void TimelineRecordFactory::setLayerData(JSONObject* data, long long rootNodeId) 274 { 275 setNodeData(data, rootNodeId); 276 } 277 278 void 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 285 PassRefPtr<JSONObject> TimelineRecordFactory::createFrameData(int frameId) 286 { 287 RefPtr<JSONObject> data = JSONObject::create(); 288 data->setNumber("id", frameId); 289 return data.release(); 290 } 291 292 void 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 299 void TimelineRecordFactory::setStyleRecalcDetails(JSONObject* data, unsigned elementCount) 300 { 301 data->setNumber("elementCount", elementCount); 302 } 303 304 void 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 312 PassRefPtr<JSONObject> TimelineRecordFactory::createEmbedderCallbackData(const String& callbackName) 313 { 314 RefPtr<JSONObject> data = JSONObject::create(); 315 data->setString("callbackName", callbackName); 316 return data.release(); 317 } 318 319 String TimelineRecordFactory::type(TypeBuilder::Timeline::TimelineEvent* event) 320 { 321 String type; 322 event->type(&type); 323 return type; 324 } 325 326 } // namespace WebCore 327 328