예제 #1
0
bool ClientApp::OnProcessMessageReceived(
    CefRefPtr<CefBrowser> browser,
    CefProcessId source_process,
    CefRefPtr<CefProcessMessage> message) {
  ASSERT(source_process == PID_BROWSER);

  bool handled = false;

  RenderDelegateSet::iterator it = render_delegates_.begin();
  for (; it != render_delegates_.end() && !handled; ++it) {
    handled = (*it)->OnProcessMessageReceived(this, browser, source_process,
                                              message);
  }

  if (handled)
    return true;

  // Execute the registered JavaScript callback if any.
  if (!callback_map_.empty()) {
    CefString message_name = message->GetName();
    CallbackMap::const_iterator it = callback_map_.find(
        std::make_pair(message_name.ToString(),
                       browser->GetIdentifier()));
    if (it != callback_map_.end()) {
      // Keep a local reference to the objects. The callback may remove itself
      // from the callback map.
      CefRefPtr<CefV8Context> context = it->second.first;
      CefRefPtr<CefV8Value> callback = it->second.second;

      // Enter the context.
      context->Enter();

      CefV8ValueList arguments;

      // First argument is the message name.
      arguments.push_back(CefV8Value::CreateString(message_name));

      // Second argument is the list of message arguments.
      CefRefPtr<CefListValue> list = message->GetArgumentList();
      CefRefPtr<CefV8Value> args =
          CefV8Value::CreateArray(static_cast<int>(list->GetSize()));
      SetList(list, args);
      arguments.push_back(args);

      // Execute the callback.
      CefRefPtr<CefV8Value> retval = callback->ExecuteFunction(NULL, arguments);
      if (retval.get()) {
        if (retval->IsBool())
          handled = retval->GetBoolValue();
      }

      // Exit the context.
      context->Exit();
    }
  }

  return handled;
}
예제 #2
0
// synchronously send a string from Node to browser, then return string result from browser to Node
Handle<Value> Window::SendSync(const Arguments& args) {
  HandleScope scope;

  NativeWindow *window = ObjectWrap::Unwrap<NativeWindow> (args.This());

  if (window->GetBrowser()) {
    // find browser's v8 context
    CefRefPtr<CefV8Context> context = window->GetBrowser()->GetMainFrame()->GetV8Context();

    // ensure it's usable and enter
    if (context.get() && context->Enter()) {
      // try to get "appjs.onmessage" function
      CefRefPtr<CefV8Value> appjsObject = context->GetGlobal()->GetValue("appjs");
      CefRefPtr<CefV8Value> callback = appjsObject->GetValue("onmessage");
      if (callback.get()) {

        // convert Node V8 string to Cef V8 string
        CefV8ValueList argsOut;
        argsOut.push_back(CefV8Value::CreateString(V8StringToChar(args[0]->ToString())));

        // execute window.appjs fuction, passing in the string,
        // then convert the return value from a CefValue to a Node V8 string
        Handle<String> ret = CefStringToV8(callback->ExecuteFunction(appjsObject, argsOut)->GetStringValue());

        // exit browser v8 context, return string result to Node caller
        context->Exit();
        return scope.Close(ret);
      }
    }
  }
  // likely error condition
  return scope.Close(Undefined());
}
void FUnrealCEFSubProcessRemoteScripting::CefToV8Arglist(CefRefPtr<CefListValue> List, CefV8ValueList& Values)
{
	for (size_t i = 0; i < List->GetSize(); ++i)
	{
		Values.push_back(CefToV8(List, i));
	}
}
예제 #4
0
void CaffeineClientApp::NonBlockingSocketWrite(SOCKET s)
{
    auto wb = wbMap.find(s);  //  s should exist
    auto& data_list = wb->second;

    //  What if an error happens in the middle of draining the list
    while(data_list.size())
    {
        auto data = data_list.front();
        CaffeineSocketClient sc = scMap.find(s)->second;
        //  Write the data and call the callback
        auto bytes_sent = sc.send(data.first.data(), data.first.size(), 0);

        if(bytes_sent>=0 && static_cast<int>(data.first.size())>bytes_sent)
        {
            data.first.erase(bytes_sent);
        }
        else
        {
            //  Call the callback
            auto ctx = data.second.first;
            ctx->Enter();

            CefRefPtr<CefV8Value> CallbackArg1;
            CefRefPtr<CefV8Value> CallbackArg2 = CefV8Value::CreateObject(NULL);

            if(bytes_sent == SOCKET_ERROR)
            {
                int error_code = WSAGetLastError();
                if (WSAEWOULDBLOCK != error_code && 0 != error_code)
                {
                    CallbackArg1 = CefV8Value::CreateBool(true);
                    CallbackArg2->SetValue("status", CefV8Value::CreateString("error"), V8_PROPERTY_ATTRIBUTE_NONE);
                    CallbackArg2->SetValue("errorCode", CefV8Value::CreateInt(::WSAGetLastError()), V8_PROPERTY_ATTRIBUTE_NONE);
                    CallbackArg2->SetValue("handle", CefV8Value::CreateInt(s), V8_PROPERTY_ATTRIBUTE_NONE);
                }
                else
                {
                    //  The socket can't write anymore.
                    ctx->Exit();
                    break;
                }
            }
            else
            {
                CallbackArg1 = CefV8Value::CreateNull();
                CallbackArg2->SetValue("status", CefV8Value::CreateString("success"), V8_PROPERTY_ATTRIBUTE_NONE);
            }

            data_list.pop_front();
            CefV8ValueList args;
            args.push_back(CallbackArg1);
            args.push_back(CallbackArg2);
            data.second.second->ExecuteFunction(NULL, args);

            ctx->Exit();
        }
    }
}
예제 #5
0
ChromiumDLL::JSObjHandle JavaScriptObject::executeFunction(ChromiumDLL::JavaScriptFunctionArgs *args)
{
	if (!isFunction())
		return GetJSFactory()->CreateException("Not a function!");

	if (!args)
		return GetJSFactory()->CreateException("Args are null for function call");

	JavaScriptContext* context = (JavaScriptContext*)args->context;
	JavaScriptObject* jso = (JavaScriptObject*)args->object.get();

	CefV8ValueList argList;

	for (int x=0; x<args->argc; x++)
	{
		JavaScriptObject* jsoa = (JavaScriptObject*)args->argv[x].get();

		if (jsoa)
			argList.push_back(jsoa->getCefV8());
		else
			argList.push_back(NULL);
	}

	CefRefPtr<CefV8Value> retval;
	CefString exception;

	bool res = m_pObject->ExecuteFunctionWithContext(context->getCefV8(), jso?jso->getCefV8():NULL, argList, retval, exception);

	if (!res)
	{
		if (exception.c_str())
			return GetJSFactory()->CreateException(exception.c_str());

		return GetJSFactory()->CreateException("failed to run function");
	}

	if (!retval)
		return NULL;

	return new JavaScriptObject(retval);
}
예제 #6
0
void CallbackTask::Execute()
{
	m_v8Ctx->Enter();
	if (m_Func&&m_Func->IsFunction())
	{
		CefRefPtr<CefV8Value> jsonRet;
		jsonRet=CefV8Value::CreateString(CefString(m_strJson));
		CefV8ValueList retList;
		retList.push_back(jsonRet);
		m_Func->ExecuteFunction(m_Object,retList);
	}
	m_v8Ctx->Exit();
}
예제 #7
0
void CSJsSocket::OnRead(int fd, short ev)
{
    char buffer[1024];
    int len = Read(buffer, sizeof(buffer));
    if (len == 0 || len == -1)
    {
        if (len == -1 && mErrorCallback)
        {
            CefV8ValueList args;
            CefRefPtr<CefV8Value> retval;
            CefRefPtr<CefV8Exception> exception;     
            
            mErrorCallback->ExecuteFunctionWithContext(mErrorContext, NULL, args, retval, exception, false);            
        }
        
        Close();

		event_del(&mEventRead);
                
		return;
	}
    else
    {
        // we read something
        if (mReadCallback)
        {
            CefV8ValueList args;
            CefRefPtr<CefV8Value> retval;
            CefRefPtr<CefV8Exception> exception;     
                        
            std::string data(buffer, len);
            args.push_back(CefV8Value::CreateString(data));
            
            mReadCallback->ExecuteFunctionWithContext(mReadContext, NULL, args, retval, exception, false);
        }
    }
}
예제 #8
0
bool Application::OnProcessMessageReceived(
	CefRefPtr<CefBrowser> InBrowser,
	CefProcessId InSourceProcess,
	CefRefPtr<CefProcessMessage> InMessage)
{
	ASSERT(InSourceProcess == PID_BROWSER); // call should have come from browser process.

	if (!Hooks.empty())
	{
		CefString MessageName = InMessage->GetName();
		JSHookMap::iterator it = Hooks.find(std::make_pair(MessageName, InBrowser->GetIdentifier()));
		if (it != Hooks.end())
		{
			// invoke JS callback
			JSHook Hook(it->second);

			Hook.Context->Enter();

			CefRefPtr<CefListValue> MessageArguments = InMessage->GetArgumentList();
			const int NumMessageArguments = (int)MessageArguments->GetSize();

			// convert message arguments
			CefV8ValueList Arguments;

			for (int i = 0; i < NumMessageArguments; ++i)
			{
				Arguments.push_back(ListItemToV8Value_RenderThread(MessageArguments, i));
			}

			Hook.Function->ExecuteFunction(nullptr, Arguments);
			Hook.Context->Exit();
			return true;
		}
	}

	return false;
}
예제 #9
0
bool ClientApp::OnProcessMessageReceived(
        CefRefPtr<CefBrowser> browser,
        CefProcessId source_process,
        CefRefPtr<CefProcessMessage> message) {
    ASSERT(source_process == PID_BROWSER);

    bool handled = false;

    // Execute delegate callbacks.
    RenderDelegateSet::iterator it = render_delegates_.begin();
    for (; it != render_delegates_.end() && !handled; ++it) {
        handled = (*it)->OnProcessMessageReceived(this, browser, source_process, message);
    }

    if (!handled) {
        if (message->GetName() == "invokeCallback") {
            // This is called by the appshell extension handler to invoke the asynchronous 
            // callback function
            
            CefRefPtr<CefListValue> messageArgs = message->GetArgumentList();
            int32 callbackId = messageArgs->GetInt(0);
                    
            CefRefPtr<CefV8Context> context = callback_map_[callbackId].first;
            CefRefPtr<CefV8Value> callbackFunction = callback_map_[callbackId].second;
            CefV8ValueList arguments;
            context->Enter();
            
            // Sanity check to make sure the context is still attched to a browser.
            // Async callbacks could be initiated after a browser instance has been deleted,
            // which can lead to bad things. If the browser instance has been deleted, don't
            // invoke this callback. 
            if (context->GetBrowser()) {
                for (size_t i = 1; i < messageArgs->GetSize(); i++) {
                    arguments.push_back(ListValueToV8Value(messageArgs, i));
                }
                
                callbackFunction->ExecuteFunction(NULL, arguments);
            }
            
            context->Exit();
            
            callback_map_.erase(callbackId);
        } else if (message->GetName() == "executeCommand") {
            // This is called by the browser process to execute a command via JavaScript
            // 
            // The first argument is the command name. This is required.
            // The second argument is a message id. This is optional. If set, a response
            // message will be sent back to the browser process.
            
            CefRefPtr<CefListValue> messageArgs = message->GetArgumentList();
            CefString commandName = messageArgs->GetString(0);
            int messageId = messageArgs->GetSize() > 1 ? messageArgs->GetInt(1) : -1;
            bool handled = false;
            
            StContextScope ctx(browser->GetMainFrame()->GetV8Context());
            
            CefRefPtr<CefV8Value> global = ctx.GetContext()->GetGlobal();
            
            if (global->HasValue("brackets")) { 
                
                CefRefPtr<CefV8Value> brackets = global->GetValue("brackets");
                
                if (brackets->HasValue("shellAPI")) {
                    
                    CefRefPtr<CefV8Value> shellAPI = brackets->GetValue("shellAPI");
                    
                    if (shellAPI->HasValue("executeCommand")) {
                        
                        CefRefPtr<CefV8Value> executeCommand = shellAPI->GetValue("executeCommand");
                        
                        if (executeCommand->IsFunction()) {
                            
                            CefRefPtr<CefV8Value> retval;
                            CefV8ValueList args;
                            args.push_back(CefV8Value::CreateString(commandName));
                            
                            retval = executeCommand->ExecuteFunction(global, args);
                            
                            if (retval) {
                                handled = retval->GetBoolValue();
                            }
                        }
                    }
                }
            }
            
            // Return a message saying whether or not the command was handled
            if (messageId != -1) {
                CefRefPtr<CefProcessMessage> result = CefProcessMessage::Create("executeCommandCallback");
                result->GetArgumentList()->SetInt(0, messageId);
                result->GetArgumentList()->SetBool(1, handled);
                
                browser->SendProcessMessage(PID_BROWSER, result);
            }
        }
    }
    
    return handled;
}
예제 #10
0
JNIEXPORT jboolean JNICALL Java_org_limewire_cef_CefV8Value_1N_N_1ExecuteFunction
  (JNIEnv *env, jobject obj, jobject params)
{
	CefRefPtr<CefV8Value> value(
		(CefV8Value*)GetCefBaseFromJNIObject(env, obj));
	if(!value.get())
		return JNI_FALSE;

	jclass params_cls = env->GetObjectClass(params);

	// Retrieve the object member.
	jobject object_obj = NULL;
	{
		jfieldID fieldID = env->GetFieldID(params_cls, "object",
			"Lorg/limewire/cef/CefV8Value;");
		if(fieldID != 0)
			object_obj = env->GetObjectField(params, fieldID);
		else
			env->ExceptionClear();
	}
	if(!object_obj)
		return JNI_FALSE;

	CefRefPtr<CefV8Value> object(
		(CefV8Value*)GetCefBaseFromJNIObject(env, object_obj));
	if(!object.get())
		return JNI_FALSE;

	// Retrieve the argument member.
	jobjectArray arg_arr = NULL;
	{
		jfieldID fieldID = env->GetFieldID(params_cls, "owner",
			"[Lorg/limewire/cef/CefV8Value;");
		if(fieldID != 0)
			arg_arr = (jobjectArray)env->GetObjectField(params, fieldID);
		else
			env->ExceptionClear();
	}
	if(!arg_arr)
		return JNI_FALSE;

	CefV8ValueList argList;
	int len = env->GetArrayLength(arg_arr);

	for(int i = 0; i < len; i++)
	{
		jobject cobj = env->GetObjectArrayElement(arg_arr, i);
		if(!cobj)
			continue;

		CefRefPtr<CefV8Value> argobj(
			(CefV8Value*)GetCefBaseFromJNIObject(env, cobj));
		if(!argobj.get())
			continue;

		argList.push_back(argobj);
	}

	CefString exception;
	
	// Execute the function.
	CefRefPtr<CefV8Value> retVal = value->ExecuteFunction(object, argList);

	// Set the return value member.
	{
		jfieldID fieldID = env->GetFieldID(params_cls, "retval",
			"Lorg/limewire/cef/CefV8Value;");
		if(fieldID != 0)
		{
			jobject robj = NULL;
			if(retVal.get())
			{
				robj = CreateJNIObject(env, "org/limewire/cef/CefV8Value_N",
					retVal.get(), (long)retVal.get());
			}
			env->SetObjectField(params, fieldID, robj);
		}
		else
		{
			env->ExceptionClear();
		}
	}

	// Set the exception member.
	{
		jfieldID fieldID = env->GetFieldID(params_cls, "exception",
			"Ljava/lang/String;");
		if(fieldID != 0)
		{
			env->SetObjectField(params, fieldID,
				CreateJNIString(env, exception));
		}
		else
		{
			env->ExceptionClear();
		}
	}

	return JNI_TRUE;
}
예제 #11
0
bool CaffeineClientApp::InvokeSocketMethod(SOCKET s, CefString state, int32 error_code)
{
    bool retval = false;

    auto i = sMap.find(s);
    if(i!=sMap.end())
    {
        //  First, try looking up the callback in the socket callback map.
        auto cb = i->second.find(state);
        if(cb!=i->second.end())
        {
            auto ctx = (cb->second).first;
            ctx->Enter();
            CefV8ValueList args;
            CefRefPtr<CefV8Value> CallbackArg = CefV8Value::CreateObject(NULL);
            CallbackArg->SetValue("handle", CefV8Value::CreateInt(s), V8_PROPERTY_ATTRIBUTE_NONE);

            //  If it's an error, it's handled a little differently.
            if (state == "error")
            {
                CallbackArg->SetValue("errorCode", CefV8Value::CreateInt(error_code), V8_PROPERTY_ATTRIBUTE_NONE);
            }
            //  The other cases have two arguments.
            else if (state != "close") //  "read" or "connect" cases
            {
                args.push_back(CefV8Value::CreateNull());
                CallbackArg->SetValue("status", CefV8Value::CreateString("success"), V8_PROPERTY_ATTRIBUTE_NONE);

                if (state == "read")
                {
                    CaffeineSocketClient sc = scMap.find(s)->second;

                    vector<char> buffer(4096);
                    int bytes_recvd = sc.recv(&buffer.front(), buffer.size()-1, 0);
                    //  TODO:  Handle real errors on a read.
                    if(bytes_recvd<=0 /*&& (WSAEWOULDBLOCK == error_code || 0 == error_code)*/) 
                    {
                        bytes_recvd = 0;
                        NonBlockingSocketWrite(s);
                        ctx->Exit();
                        return true;
                    }
                    buffer[bytes_recvd] = 0;

                    CallbackArg->SetValue("nBytes", CefV8Value::CreateInt(bytes_recvd), V8_PROPERTY_ATTRIBUTE_NONE);
                    CallbackArg->SetValue("data", CefV8Value::CreateString(buffer.data()), V8_PROPERTY_ATTRIBUTE_NONE);
                }
            }
            args.push_back(CallbackArg);

            (cb->second).second->ExecuteFunction(NULL, args);
            ctx->Exit();

            //  TODO:  We should actually call read to make sure we've read all of the data before 
            //  TODO:  cleaning up.  Probably should do the same thing for the error case too.
            if (state == "error" || state == "close")
            {
                closesocket(s);
                //  Clean up the sockets maps
                RemoveSocketCallback(s);
                wbMap.erase(s);
                scMap.erase(s);
            }

            retval = true;
        }
        //  Otherwise, if we can write handle it.
        else if (state == "write")
        {
            NonBlockingSocketWrite(s);
            retval = true;
        }
    }

    return retval;
}