1 /* 2 * Copyright (C) 2012 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/InjectedScriptCanvasModule.h" 33 34 #include "InjectedScriptCanvasModuleSource.h" 35 #include "bindings/v8/ScriptFunctionCall.h" 36 #include "bindings/v8/ScriptObject.h" 37 38 using WebCore::TypeBuilder::Array; 39 using WebCore::TypeBuilder::Canvas::ResourceId; 40 using WebCore::TypeBuilder::Canvas::ResourceState; 41 using WebCore::TypeBuilder::Canvas::TraceLog; 42 using WebCore::TypeBuilder::Canvas::TraceLogId; 43 using WebCore::TypeBuilder::Runtime::RemoteObject; 44 45 namespace WebCore { 46 47 InjectedScriptCanvasModule::InjectedScriptCanvasModule() 48 : InjectedScriptModule("InjectedScriptCanvasModule") 49 { 50 } 51 52 InjectedScriptCanvasModule InjectedScriptCanvasModule::moduleForState(InjectedScriptManager* injectedScriptManager, ScriptState* scriptState) 53 { 54 InjectedScriptCanvasModule result; 55 result.ensureInjected(injectedScriptManager, scriptState); 56 return result; 57 } 58 59 String InjectedScriptCanvasModule::source() const 60 { 61 return String(reinterpret_cast<const char*>(InjectedScriptCanvasModuleSource_js), sizeof(InjectedScriptCanvasModuleSource_js)); 62 } 63 64 ScriptObject InjectedScriptCanvasModule::wrapCanvas2DContext(const ScriptObject& context) 65 { 66 return callWrapContextFunction("wrapCanvas2DContext", context); 67 } 68 69 ScriptObject InjectedScriptCanvasModule::wrapWebGLContext(const ScriptObject& glContext) 70 { 71 return callWrapContextFunction("wrapWebGLContext", glContext); 72 } 73 74 ScriptObject InjectedScriptCanvasModule::callWrapContextFunction(const String& functionName, const ScriptObject& context) 75 { 76 ScriptFunctionCall function(injectedScriptObject(), functionName); 77 function.appendArgument(context); 78 bool hadException = false; 79 ScriptValue resultValue = callFunctionWithEvalEnabled(function, hadException); 80 if (hadException || resultValue.hasNoValue() || !resultValue.isObject()) { 81 ASSERT_NOT_REACHED(); 82 return ScriptObject(); 83 } 84 return ScriptObject(context.scriptState(), resultValue); 85 } 86 87 void InjectedScriptCanvasModule::markFrameEnd() 88 { 89 ScriptFunctionCall function(injectedScriptObject(), "markFrameEnd"); 90 RefPtr<JSONValue> resultValue; 91 makeCall(function, &resultValue); 92 ASSERT(resultValue); 93 } 94 95 void InjectedScriptCanvasModule::captureFrame(ErrorString* errorString, TraceLogId* traceLogId) 96 { 97 callStartCapturingFunction("captureFrame", errorString, traceLogId); 98 } 99 100 void InjectedScriptCanvasModule::startCapturing(ErrorString* errorString, TraceLogId* traceLogId) 101 { 102 callStartCapturingFunction("startCapturing", errorString, traceLogId); 103 } 104 105 void InjectedScriptCanvasModule::callStartCapturingFunction(const String& functionName, ErrorString* errorString, TraceLogId* traceLogId) 106 { 107 ScriptFunctionCall function(injectedScriptObject(), functionName); 108 RefPtr<JSONValue> resultValue; 109 makeCall(function, &resultValue); 110 if (!resultValue || resultValue->type() != JSONValue::TypeString || !resultValue->asString(traceLogId)) 111 *errorString = "Internal error: " + functionName; 112 } 113 114 void InjectedScriptCanvasModule::stopCapturing(ErrorString* errorString, const TraceLogId& traceLogId) 115 { 116 callVoidFunctionWithTraceLogIdArgument("stopCapturing", errorString, traceLogId); 117 } 118 119 void InjectedScriptCanvasModule::dropTraceLog(ErrorString* errorString, const TraceLogId& traceLogId) 120 { 121 callVoidFunctionWithTraceLogIdArgument("dropTraceLog", errorString, traceLogId); 122 } 123 124 void InjectedScriptCanvasModule::callVoidFunctionWithTraceLogIdArgument(const String& functionName, ErrorString* errorString, const TraceLogId& traceLogId) 125 { 126 ScriptFunctionCall function(injectedScriptObject(), functionName); 127 function.appendArgument(traceLogId); 128 bool hadException = false; 129 callFunctionWithEvalEnabled(function, hadException); 130 ASSERT(!hadException); 131 if (hadException) 132 *errorString = "Internal error: " + functionName; 133 } 134 135 void InjectedScriptCanvasModule::traceLog(ErrorString* errorString, const TraceLogId& traceLogId, const int* startOffset, const int* maxLength, RefPtr<TraceLog>* traceLog) 136 { 137 ScriptFunctionCall function(injectedScriptObject(), "traceLog"); 138 function.appendArgument(traceLogId); 139 if (startOffset) 140 function.appendArgument(*startOffset); 141 if (maxLength) 142 function.appendArgument(*maxLength); 143 RefPtr<JSONValue> resultValue; 144 makeCall(function, &resultValue); 145 if (!resultValue || resultValue->type() != JSONValue::TypeObject) { 146 if (!resultValue->asString(errorString)) 147 *errorString = "Internal error: traceLog"; 148 return; 149 } 150 *traceLog = TraceLog::runtimeCast(resultValue); 151 } 152 153 void InjectedScriptCanvasModule::replayTraceLog(ErrorString* errorString, const TraceLogId& traceLogId, int stepNo, RefPtr<ResourceState>* result, double* replayTime) 154 { 155 ScriptFunctionCall function(injectedScriptObject(), "replayTraceLog"); 156 function.appendArgument(traceLogId); 157 function.appendArgument(stepNo); 158 RefPtr<JSONValue> resultValue; 159 makeCall(function, &resultValue); 160 if (!resultValue || resultValue->type() != JSONValue::TypeObject) { 161 if (!resultValue->asString(errorString)) 162 *errorString = "Internal error: replayTraceLog"; 163 return; 164 } 165 RefPtr<JSONObject> resultObject = resultValue->asObject(); 166 RefPtr<JSONObject> resourceStateObject = resultObject->getObject("resourceState"); 167 if (!resourceStateObject) { 168 *errorString = "Internal error: replayTraceLog: no resourceState"; 169 return; 170 } 171 *result = ResourceState::runtimeCast(resourceStateObject); 172 if (!resultObject->getNumber("replayTime", replayTime)) 173 *errorString = "Internal error: replayTraceLog: no replayTime"; 174 } 175 176 void InjectedScriptCanvasModule::resourceState(ErrorString* errorString, const TraceLogId& traceLogId, const ResourceId& resourceId, RefPtr<ResourceState>* result) 177 { 178 ScriptFunctionCall function(injectedScriptObject(), "resourceState"); 179 function.appendArgument(traceLogId); 180 function.appendArgument(resourceId); 181 RefPtr<JSONValue> resultValue; 182 makeCall(function, &resultValue); 183 if (!resultValue || resultValue->type() != JSONValue::TypeObject) { 184 if (!resultValue->asString(errorString)) 185 *errorString = "Internal error: resourceState"; 186 return; 187 } 188 *result = ResourceState::runtimeCast(resultValue); 189 } 190 191 void InjectedScriptCanvasModule::evaluateTraceLogCallArgument(ErrorString* errorString, const TraceLogId& traceLogId, int callIndex, int argumentIndex, const String& objectGroup, RefPtr<RemoteObject>* result, RefPtr<ResourceState>* resourceState) 192 { 193 ScriptFunctionCall function(injectedScriptObject(), "evaluateTraceLogCallArgument"); 194 function.appendArgument(traceLogId); 195 function.appendArgument(callIndex); 196 function.appendArgument(argumentIndex); 197 function.appendArgument(objectGroup); 198 RefPtr<JSONValue> resultValue; 199 makeCall(function, &resultValue); 200 if (!resultValue || resultValue->type() != JSONValue::TypeObject) { 201 if (!resultValue->asString(errorString)) 202 *errorString = "Internal error: evaluateTraceLogCallArgument"; 203 return; 204 } 205 RefPtr<JSONObject> resultObject = resultValue->asObject(); 206 RefPtr<JSONObject> remoteObject = resultObject->getObject("result"); 207 if (remoteObject) 208 *result = RemoteObject::runtimeCast(remoteObject); 209 RefPtr<JSONObject> resourceStateObject = resultObject->getObject("resourceState"); 210 if (resourceStateObject) 211 *resourceState = ResourceState::runtimeCast(resourceStateObject); 212 if (!remoteObject && !resourceStateObject) 213 *errorString = "Internal error: no result and no resource state"; 214 } 215 216 } // namespace WebCore 217