Home | History | Annotate | Download | only in inspector
      1 /*
      2  * Copyright (C) 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 "core/inspector/InspectorRuntimeAgent.h"
     33 
     34 #include "bindings/v8/ScriptDebugServer.h"
     35 #include "bindings/v8/ScriptState.h"
     36 #include "core/inspector/InjectedScript.h"
     37 #include "core/inspector/InjectedScriptManager.h"
     38 #include "core/inspector/InspectorState.h"
     39 #include "platform/JSONValues.h"
     40 
     41 using WebCore::TypeBuilder::Runtime::ExecutionContextDescription;
     42 
     43 namespace WebCore {
     44 
     45 namespace InspectorRuntimeAgentState {
     46 static const char runtimeEnabled[] = "runtimeEnabled";
     47 };
     48 
     49 static bool asBool(const bool* const b)
     50 {
     51     return b ? *b : false;
     52 }
     53 
     54 InspectorRuntimeAgent::InspectorRuntimeAgent(InjectedScriptManager* injectedScriptManager, ScriptDebugServer* scriptDebugServer)
     55     : InspectorBaseAgent<InspectorRuntimeAgent>("Runtime")
     56     , m_enabled(false)
     57     , m_frontend(0)
     58     , m_injectedScriptManager(injectedScriptManager)
     59     , m_scriptDebugServer(scriptDebugServer)
     60 {
     61 }
     62 
     63 InspectorRuntimeAgent::~InspectorRuntimeAgent()
     64 {
     65 }
     66 
     67 static ScriptDebugServer::PauseOnExceptionsState setPauseOnExceptionsState(ScriptDebugServer* scriptDebugServer, ScriptDebugServer::PauseOnExceptionsState newState)
     68 {
     69     ASSERT(scriptDebugServer);
     70     ScriptDebugServer::PauseOnExceptionsState presentState = scriptDebugServer->pauseOnExceptionsState();
     71     if (presentState != newState)
     72         scriptDebugServer->setPauseOnExceptionsState(newState);
     73     return presentState;
     74 }
     75 
     76 void InspectorRuntimeAgent::evaluate(ErrorString* errorString, const String& expression, const String* const objectGroup, const bool* const includeCommandLineAPI, const bool* const doNotPauseOnExceptionsAndMuteConsole, const int* executionContextId, const bool* const returnByValue, const bool* generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
     77 {
     78     InjectedScript injectedScript = injectedScriptForEval(errorString, executionContextId);
     79     if (injectedScript.isEmpty())
     80         return;
     81     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = ScriptDebugServer::DontPauseOnExceptions;
     82     if (asBool(doNotPauseOnExceptionsAndMuteConsole))
     83         previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);
     84     if (asBool(doNotPauseOnExceptionsAndMuteConsole))
     85         muteConsole();
     86 
     87     injectedScript.evaluate(errorString, expression, objectGroup ? *objectGroup : "", asBool(includeCommandLineAPI), asBool(returnByValue), asBool(generatePreview), &result, wasThrown);
     88 
     89     if (asBool(doNotPauseOnExceptionsAndMuteConsole)) {
     90         unmuteConsole();
     91         setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState);
     92     }
     93 }
     94 
     95 void InspectorRuntimeAgent::callFunctionOn(ErrorString* errorString, const String& objectId, const String& expression, const RefPtr<JSONArray>* const optionalArguments, const bool* const doNotPauseOnExceptionsAndMuteConsole, const bool* const returnByValue, const bool* generatePreview, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown)
     96 {
     97     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
     98     if (injectedScript.isEmpty()) {
     99         *errorString = "Inspected frame has gone";
    100         return;
    101     }
    102     String arguments;
    103     if (optionalArguments)
    104         arguments = (*optionalArguments)->toJSONString();
    105 
    106     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = ScriptDebugServer::DontPauseOnExceptions;
    107     if (asBool(doNotPauseOnExceptionsAndMuteConsole))
    108         previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);
    109     if (asBool(doNotPauseOnExceptionsAndMuteConsole))
    110         muteConsole();
    111 
    112     injectedScript.callFunctionOn(errorString, objectId, expression, arguments, asBool(returnByValue), asBool(generatePreview), &result, wasThrown);
    113 
    114     if (asBool(doNotPauseOnExceptionsAndMuteConsole)) {
    115         unmuteConsole();
    116         setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState);
    117     }
    118 }
    119 
    120 void InspectorRuntimeAgent::getProperties(ErrorString* errorString, const String& objectId, const bool* ownProperties, const bool* accessorPropertiesOnly, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::PropertyDescriptor> >& result, RefPtr<TypeBuilder::Array<TypeBuilder::Runtime::InternalPropertyDescriptor> >& internalProperties)
    121 {
    122     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
    123     if (injectedScript.isEmpty()) {
    124         *errorString = "Inspected frame has gone";
    125         return;
    126     }
    127 
    128     ScriptDebugServer::PauseOnExceptionsState previousPauseOnExceptionsState = setPauseOnExceptionsState(m_scriptDebugServer, ScriptDebugServer::DontPauseOnExceptions);
    129     muteConsole();
    130 
    131     bool accessorPropertiesOnlyValue = accessorPropertiesOnly && *accessorPropertiesOnly;
    132     injectedScript.getProperties(errorString, objectId, ownProperties && *ownProperties, accessorPropertiesOnlyValue, &result);
    133 
    134     if (!accessorPropertiesOnlyValue)
    135         injectedScript.getInternalProperties(errorString, objectId, &internalProperties);
    136 
    137     unmuteConsole();
    138     setPauseOnExceptionsState(m_scriptDebugServer, previousPauseOnExceptionsState);
    139 }
    140 
    141 void InspectorRuntimeAgent::releaseObject(ErrorString*, const String& objectId)
    142 {
    143     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
    144     if (!injectedScript.isEmpty())
    145         injectedScript.releaseObject(objectId);
    146 }
    147 
    148 void InspectorRuntimeAgent::releaseObjectGroup(ErrorString*, const String& objectGroup)
    149 {
    150     m_injectedScriptManager->releaseObjectGroup(objectGroup);
    151 }
    152 
    153 void InspectorRuntimeAgent::run(ErrorString*)
    154 {
    155 }
    156 
    157 void InspectorRuntimeAgent::isRunRequired(ErrorString*, bool* out_result)
    158 {
    159     *out_result = false;
    160 }
    161 
    162 void InspectorRuntimeAgent::setFrontend(InspectorFrontend* frontend)
    163 {
    164     m_frontend = frontend->runtime();
    165 }
    166 
    167 void InspectorRuntimeAgent::clearFrontend()
    168 {
    169     m_frontend = 0;
    170     String errorString;
    171     disable(&errorString);
    172 }
    173 
    174 void InspectorRuntimeAgent::restore()
    175 {
    176     if (m_state->getBoolean(InspectorRuntimeAgentState::runtimeEnabled)) {
    177         m_scriptStateToId.clear();
    178         m_frontend->executionContextsCleared();
    179         String error;
    180         enable(&error);
    181     }
    182 }
    183 
    184 void InspectorRuntimeAgent::enable(ErrorString* errorString)
    185 {
    186     if (m_enabled)
    187         return;
    188 
    189     m_enabled = true;
    190     m_state->setBoolean(InspectorRuntimeAgentState::runtimeEnabled, true);
    191 }
    192 
    193 void InspectorRuntimeAgent::disable(ErrorString* errorString)
    194 {
    195     if (!m_enabled)
    196         return;
    197 
    198     m_scriptStateToId.clear();
    199     m_enabled = false;
    200     m_state->setBoolean(InspectorRuntimeAgentState::runtimeEnabled, false);
    201 }
    202 
    203 void InspectorRuntimeAgent::addExecutionContextToFrontend(ScriptState* scriptState, bool isPageContext, const String& name, const String& frameId)
    204 {
    205     int executionContextId = injectedScriptManager()->injectedScriptIdFor(scriptState);
    206     m_scriptStateToId.set(scriptState, executionContextId);
    207     m_frontend->executionContextCreated(ExecutionContextDescription::create()
    208         .setId(executionContextId)
    209         .setIsPageContext(isPageContext)
    210         .setName(name)
    211         .setFrameId(frameId)
    212         .release());
    213 }
    214 
    215 } // namespace WebCore
    216 
    217