bool FUnrealCEFSubProcessRemoteScripting::HandleExecuteJSFunctionMessage(CefRefPtr<CefListValue> MessageArguments) { FGuid Guid; // Message arguments are CallbackGuid, FunctionArguments, bIsError if (MessageArguments->GetSize() != 3 || MessageArguments->GetType(0) != VTYPE_STRING || MessageArguments->GetType(1) != VTYPE_LIST || MessageArguments->GetType(2) != VTYPE_BOOL) { // Wrong message argument types or count return false; } if (!FGuid::Parse(FString(MessageArguments->GetString(0).ToWString().c_str()), Guid)) { // Invalid GUID return false; } if (!CallbackRegistry.Contains(Guid)) { // Unknown callback id return false; } auto Callback = CallbackRegistry[Guid]; { ScopedV8Context ContextScope(Callback.Context); bool bIsErrorCallback = MessageArguments->GetBool(2); CefRefPtr<CefV8Value> Function = bIsErrorCallback?Callback.OnError:Callback.Function; if (!Function.get()) { // Either invalid entry or no error handler return false; } CefV8ValueList FunctionArguments; CefToV8Arglist(MessageArguments->GetList(1), FunctionArguments); CefRefPtr<CefV8Value> Retval = Function->ExecuteFunction(Callback.Object, FunctionArguments); if (!Retval.get()) { // Function call resulted in an error return false; } // Remove callback if it's a one-shot callback and successful. if (Callback.bOneShot) { CallbackRegistry.Remove(Guid); } return true; } }
bool FUnrealCEFSubProcessRemoteScripting::HandleSetValueMessage(CefRefPtr<CefBrowser> Browser, CefRefPtr<CefListValue> MessageArguments) { CefRefPtr<CefFrame> MainFrame = Browser->GetMainFrame(); CefRefPtr<CefV8Context> Context = MainFrame->GetV8Context(); ScopedV8Context ContextScope(Context); CefRefPtr<CefV8Value> RootObject = Context->GetGlobal()->GetValue("ue"); if (!RootObject.get()) { // The root object should always be created on context creation. return false; } for (size_t I = 0; I < MessageArguments->GetSize(); I++) { if (MessageArguments->GetType(I) != VTYPE_DICTIONARY) { return false; } CefRefPtr<CefDictionaryValue> Argument = MessageArguments->GetDictionary(I); if (Argument->GetType("name") != VTYPE_STRING || Argument->GetType("value") != VTYPE_DICTIONARY || Argument->GetType("permanent") != VTYPE_BOOL) { // Wrong message argument types or count return false; } CefString Name = Argument->GetString("name"); CefRefPtr<CefDictionaryValue> CefValue = Argument->GetDictionary("value"); bool bPermanent = Argument->GetBool("permanent"); if (bPermanent) { int32 BrowserID = Browser->GetIdentifier(); CefRefPtr<CefDictionaryValue> Bindings; if (PermanentBindings.Contains(BrowserID)) { Bindings = PermanentBindings[BrowserID]; } else { Bindings = CefDictionaryValue::Create(); PermanentBindings.Add(BrowserID, Bindings); } Bindings->SetDictionary(Name, CefValue); } CefRefPtr<CefV8Value> Value = CefToV8(CefValue); RootObject->SetValue(Name, Value, V8_PROPERTY_ATTRIBUTE_NONE); } return true; }
static void _list_to_dict( CefRefPtr<CefListValue> & src, CefRefPtr<CefDictionaryValue> & dest, CefDictionaryValue::KeyList & keys ) { if (!src.get()) return; if (!dest.get()) dest = CefDictionaryValue::Create(); bool has_keys = keys.size() == dest->GetSize(); for (int i = 0, nsize = static_cast<int>(src->GetSize()); i < nsize; ++i) { std::string key = has_keys ? keys[i] : std::to_string(i); switch (src->GetType(i)) { case VTYPE_NULL: dest->SetNull(key); break; case VTYPE_BOOL: dest->SetBool(key, src->GetBool(i)); break; case VTYPE_INT: dest->SetInt(key, src->GetInt(i)); break; case VTYPE_DOUBLE: dest->SetDouble(key, src->GetDouble(i)); break; case VTYPE_STRING: dest->SetString(key, src->GetString(i)); break; case VTYPE_BINARY: dest->SetBinary(key, src->GetBinary(i)); break; case VTYPE_DICTIONARY: dest->SetDictionary(key, src->GetDictionary(i)); break; case VTYPE_LIST: dest->SetList(key, src->GetList(i)); break; default: assert(0); break; } } }
// ¶ªÆúkey static void _dict_to_list(CefRefPtr<CefDictionaryValue> & src, CefRefPtr<CefListValue> & dest) { if (!src.get()) return; if (!dest.get()) dest = CefListValue::Create(); CefDictionaryValue::KeyList keys; src->GetKeys(keys); int idx = 0; for (CefString & i : keys) { switch (src->GetType(i)) { case VTYPE_NULL: dest->SetNull(idx); break; case VTYPE_BOOL: dest->SetBool(idx, src->GetBool(i)); break; case VTYPE_INT: dest->SetInt(idx, src->GetInt(i)); break; case VTYPE_DOUBLE: dest->SetDouble(idx, src->GetDouble(i)); break; case VTYPE_STRING: dest->SetString(idx, src->GetString(i)); break; case VTYPE_BINARY: dest->SetBinary(idx, src->GetBinary(i)); break; case VTYPE_DICTIONARY: dest->SetDictionary(idx, src->GetDictionary(i)); break; case VTYPE_LIST: dest->SetList(idx, src->GetList(i)); break; default: assert(0); break; } ++idx; } }
/*--cef()--*/ bool App::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) { LOG_DEBUG << "renderer[" << browser->GetIdentifier() << "] " << "OnProcessMessageReceived: " << message->GetName().ToString(); if (message->GetName() == "SetIsFullscreen") { CefRefPtr<CefListValue> args = message->GetArgumentList(); bool isFullscreen = args->GetBool(0); CefRefPtr<JavascriptApi> javascriptApi = GetJavascriptApi(browser); if (javascriptApi.get()) { javascriptApi->SetIsFullscreen(isFullscreen); } return true; } LOG_ERROR << "Unhandled message in OnProcessMessageReceived"; return false; }
bool ClientHandler::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) { if (message->GetName().ToString() == "show_keyboard"){ PostCallback(callback1(WhenKeyboard, true)); }else if (message->GetName().ToString() == "hide_keyboard"){ PostCallback(callback1(WhenKeyboard, false)); }else{ CefRefPtr<CefListValue> args = message->GetArgumentList(); Upp::Vector<Upp::Value> par; for (unsigned i = 0; i < args->GetSize(); i++){ CefValueType type = args->GetType(i); switch(type){ case VTYPE_BOOL: par.Add(args->GetBool(i)); break; case VTYPE_DOUBLE: par.Add(args->GetDouble(i)); break; case VTYPE_INT: par.Add(args->GetInt(i)); break; case VTYPE_STRING: par.Add(args->GetString(i).ToString().c_str()); break; default: par.Add("OnProcessMessageReceived: unsupported parameter type"); break; } } PostCallback(callback2(WhenMessage, message->GetName().ToString(), par)); } return true; }
//////////////////////////////////////////////////////////////////// // // // Implementation: CefClient::OnProcessMessageReceived // // http://magpcss.org/ceforum/apidocs3/projects/(default)/CefClient.html#OnProcessMessageReceived(CefRefPtr%3CCefBrowser%3E,CefProcessId,CefRefPtr%3CCefProcessMessage%3E) // // // //////////////////////////////////////////////////////////////////// bool CWebView::OnProcessMessageReceived ( CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message ) { CefRefPtr<CefListValue> argList = message->GetArgumentList (); if ( message->GetName () == "TriggerLuaEvent" || message->GetName () == "TriggerServerLuaEvent" ) { // Get event name CefString eventName = argList->GetString ( 0 ); // Get number of arguments from IPC process message int numArgs = argList->GetInt ( 1 ); // Get args std::vector<std::string> args; for ( int i = 2; i < numArgs + 2; ++i ) { args.push_back ( argList->GetString ( i ) ); } // Queue event to run on the main thread auto func = std::bind ( &CWebBrowserEventsInterface::Events_OnTriggerEvent, m_pEventsInterface, SString ( eventName ), args, message->GetName () == "TriggerServerLuaEvent" ); g_pCore->GetWebCore ()->AddEventToEventQueue ( func, this, "OnProcessMessageReceived1" ); // The message was handled return true; } if ( message->GetName () == "InputFocus" ) { // Retrieve arguments from process message m_bHasInputFocus = argList->GetBool ( 0 ); // Queue event to run on the main thread auto func = std::bind ( &CWebBrowserEventsInterface::Events_OnInputFocusChanged, m_pEventsInterface, m_bHasInputFocus ); g_pCore->GetWebCore ()->AddEventToEventQueue ( func, this, "OnProcessMessageReceived2" ); } // The message wasn't handled return false; }
CefRefPtr<CefV8Value> CefDictionaryValueToV8Value( CefRefPtr<CefDictionaryValue> dictValue, int nestingLevel) { if (!dictValue->IsValid()) { DebugLog("CefDictionaryValueToV8Value() FAILED: " \ "CefDictionaryValue is invalid"); return CefV8Value::CreateNull(); } if (nestingLevel > 8) { DebugLog("CefDictionaryValueToV8Value(): WARNING: " \ "max nesting level (8) exceeded"); return CefV8Value::CreateNull(); } std::vector<CefString> keys; if (!dictValue->GetKeys(keys)) { DebugLog("CefDictionaryValueToV8Value() FAILED: " \ "dictValue->GetKeys() failed"); return CefV8Value::CreateNull(); } CefRefPtr<CefV8Value> ret = CefV8Value::CreateObject(NULL); CefRefPtr<CefBinaryValue> binaryValue; PythonCallback pyCallback; CefRefPtr<CefV8Handler> v8FunctionHandler; for (std::vector<CefString>::iterator it = keys.begin(); \ it != keys.end(); ++it) { CefString key = *it; cef_value_type_t valueType = dictValue->GetType(key); bool success; std::string callbackName = "python_callback_"; if (valueType == VTYPE_NULL) { success = ret->SetValue(key, CefV8Value::CreateNull(), V8_PROPERTY_ATTRIBUTE_NONE); } else if (valueType == VTYPE_BOOL) { success = ret->SetValue(key, CefV8Value::CreateBool(dictValue->GetBool(key)), V8_PROPERTY_ATTRIBUTE_NONE); } else if (valueType == VTYPE_INT) { success = ret->SetValue(key, CefV8Value::CreateInt(dictValue->GetInt(key)), V8_PROPERTY_ATTRIBUTE_NONE); } else if (valueType == VTYPE_DOUBLE) { success = ret->SetValue(key, CefV8Value::CreateDouble(dictValue->GetDouble(key)), V8_PROPERTY_ATTRIBUTE_NONE); } else if (valueType == VTYPE_STRING) { success = ret->SetValue(key, CefV8Value::CreateString(dictValue->GetString(key)), V8_PROPERTY_ATTRIBUTE_NONE); } else if (valueType == VTYPE_BINARY) { binaryValue = dictValue->GetBinary(key); if (binaryValue->GetSize() == sizeof(pyCallback)) { binaryValue->GetData(&pyCallback, sizeof(pyCallback), 0); v8FunctionHandler = new V8FunctionHandler( NULL, pyCallback.callbackId); // You must provide a function name to // CefV8Value::CreateFunction(), otherwise it fails. callbackName.append(AnyToString(pyCallback.callbackId)); success = ret->SetValue(key, CefV8Value::CreateFunction( callbackName, v8FunctionHandler), V8_PROPERTY_ATTRIBUTE_NONE); } else { DebugLog("CefListValueToV8Value(): WARNING: " \ "unknown binary value, setting value to null"); success = ret->SetValue(key, CefV8Value::CreateNull(), V8_PROPERTY_ATTRIBUTE_NONE); } } else if (valueType == VTYPE_DICTIONARY) { success = ret->SetValue(key, CefDictionaryValueToV8Value( dictValue->GetDictionary(key), nestingLevel + 1), V8_PROPERTY_ATTRIBUTE_NONE); } else if (valueType == VTYPE_LIST) { success = ret->SetValue(key, CefListValueToV8Value( dictValue->GetList(key), nestingLevel + 1), V8_PROPERTY_ATTRIBUTE_NONE); } else { DebugLog("CefDictionaryValueToV8Value(): WARNING: " \ "unknown type, setting value to null"); success = ret->SetValue(key, CefV8Value::CreateNull(), V8_PROPERTY_ATTRIBUTE_NONE); } if (!success) { DebugLog("CefDictionaryValueToV8Value(): WARNING: " \ "ret->SetValue() failed"); } } return ret; }
CefRefPtr<CefV8Value> CefListValueToV8Value( CefRefPtr<CefListValue> listValue, int nestingLevel) { if (!listValue->IsValid()) { DebugLog("CefListValueToV8Value() FAILED: " \ "CefDictionaryValue is invalid"); return CefV8Value::CreateNull(); } if (nestingLevel > 8) { DebugLog("CefListValueToV8Value(): WARNING: " \ "max nesting level (8) exceeded"); return CefV8Value::CreateNull(); } int listSize = (int)listValue->GetSize(); CefRefPtr<CefV8Value> ret = CefV8Value::CreateArray(listSize); CefRefPtr<CefBinaryValue> binaryValue; PythonCallback pyCallback; CefRefPtr<CefV8Handler> v8FunctionHandler; for (int key = 0; key < listSize; ++key) { cef_value_type_t valueType = listValue->GetType(key); bool success; std::string callbackName = "python_callback_"; if (valueType == VTYPE_NULL) { success = ret->SetValue(key, CefV8Value::CreateNull()); } else if (valueType == VTYPE_BOOL) { success = ret->SetValue(key, CefV8Value::CreateBool(listValue->GetBool(key))); } else if (valueType == VTYPE_INT) { success = ret->SetValue(key, CefV8Value::CreateInt(listValue->GetInt(key))); } else if (valueType == VTYPE_DOUBLE) { success = ret->SetValue(key, CefV8Value::CreateDouble(listValue->GetDouble(key))); } else if (valueType == VTYPE_STRING) { success = ret->SetValue(key, CefV8Value::CreateString(listValue->GetString(key))); } else if (valueType == VTYPE_BINARY) { binaryValue = listValue->GetBinary(key); if (binaryValue->GetSize() == sizeof(pyCallback)) { binaryValue->GetData(&pyCallback, sizeof(pyCallback), 0); v8FunctionHandler = new V8FunctionHandler( NULL, pyCallback.callbackId); // You must provide a function name to // CefV8Value::CreateFunction(), otherwise it fails. callbackName.append(AnyToString(pyCallback.callbackId)); success = ret->SetValue(key, CefV8Value::CreateFunction( callbackName, v8FunctionHandler)); } else { DebugLog("CefListValueToV8Value(): WARNING: " \ "unknown binary value, setting value to null"); success = ret->SetValue(key, CefV8Value::CreateNull()); } } else if (valueType == VTYPE_DICTIONARY) { success = ret->SetValue(key, CefDictionaryValueToV8Value( listValue->GetDictionary(key), nestingLevel + 1)); } else if (valueType == VTYPE_LIST) { success = ret->SetValue(key, CefListValueToV8Value( listValue->GetList(key), nestingLevel + 1)); } else { DebugLog("CefListValueToV8Value(): WARNING: " \ "unknown type, setting value to null"); success = ret->SetValue(key, CefV8Value::CreateNull()); } if (!success) { DebugLog("CefListValueToV8Value(): WARNING: " \ "ret->SetValue() failed"); } } return ret; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- boost::python::dict CefDictionaryValueToPy( CefRefPtr<CefDictionaryValue> d ) { boost::python::dict result; CefDictionaryValue::KeyList keys; d->GetKeys( keys ); for( size_t i = 0; i < keys.size(); i++ ) { std::string k = keys[i].ToString(); switch( d->GetType( keys[i] ) ) { case VTYPE_INT: { result[k.c_str()] = d->GetInt( keys[i] ); break; } case VTYPE_DOUBLE: { result[k.c_str()] = d->GetDouble( keys[i] ); break; } case VTYPE_BOOL: { result[k.c_str()] = d->GetBool( keys[i] ); break; } case VTYPE_STRING: { result[k.c_str()] = d->GetString( keys[i] ).ToString().c_str(); break; } case VTYPE_BINARY: { WarsCefData_t warsCefData; CefRefPtr<CefBinaryValue> binaryData = d->GetBinary( keys[i] ); binaryData->GetData( &warsCefData, sizeof( warsCefData ), 0 ); if( warsCefData.type == WARSCEF_TYPE_JSOBJECT ) { WarsCefJSObject_t warsCefJSObject; binaryData->GetData( &warsCefJSObject, sizeof( warsCefJSObject ), 0 ); CefRefPtr<JSObject> jsResultObject = new JSObject( "", warsCefJSObject.uuid ); result[k.c_str()] = boost::python::object( PyJSObject( jsResultObject ) ); } else { result[k.c_str()] = boost::python::object(); } break; } case VTYPE_DICTIONARY: { result[k.c_str()] = CefDictionaryValueToPy( d->GetDictionary( keys[i] ) ); break; } case VTYPE_LIST: { result[k.c_str()] = CefValueListToPy( d->GetList( keys[i] ) ); break; } default: { result[k.c_str()] = d->GetString( keys[i] ).ToString().c_str(); break; } } } return result; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- boost::python::list CefValueListToPy( CefRefPtr<CefListValue> l ) { boost::python::list result; for( size_t i = 0; i < l->GetSize(); i++ ) { switch( l->GetType( i ) ) { case VTYPE_INT: { result.append( l->GetInt( i ) ); break; } case VTYPE_DOUBLE: { result.append( l->GetDouble( i ) ); break; } case VTYPE_BOOL: { result.append( l->GetBool( i ) ); break; } case VTYPE_STRING: { result.append( l->GetString( i ).ToString().c_str() ); break; } case VTYPE_BINARY: { WarsCefData_t warsCefData; l->GetBinary( i )->GetData( &warsCefData, sizeof( warsCefData ), 0 ); if( warsCefData.type == WARSCEF_TYPE_JSOBJECT ) { WarsCefJSObject_t warsCefJSObject; l->GetBinary( i )->GetData( &warsCefJSObject, sizeof( warsCefJSObject ), 0 ); CefRefPtr<JSObject> jsResultObject = new JSObject( "", warsCefJSObject.uuid ); result.append( boost::python::object( PyJSObject( jsResultObject ) ) ); } else { result.append( boost::python::object() ); } break; } case VTYPE_DICTIONARY: { result.append( CefDictionaryValueToPy( l->GetDictionary( i ) ) ); break; } case VTYPE_LIST: { result.append( CefValueListToPy( l->GetList( i ) ) ); break; } default: { result.append( l->GetString( i ).ToString().c_str() ); break; } } } return result; }
bool excuteJSON(const CefString& request){ CefRefPtr<CefValue> v = CefParseJSON(request, JSON_PARSER_RFC); // 进行解析 if (v == NULL){ //callback->Failure(1, CefString(L"错误的JSON格式")); return false; } #ifdef JWebTopLog wstringstream log; log << L"JWebTopCommons#Handler#OnQuery jsons=" << request.ToWString() << L"\r\n"; writeLog(log.str()); #endif CefRefPtr<CefDictionaryValue> value = v->GetDictionary();// 按JSON字典来获取 wstring methodName = value->GetString("m").ToWString(); // 取出某字符串 if (methodName == L"loadUrl"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; CefRefPtr<CefValue> url = value->GetValue("url"); if (url == NULL)return false; jb::loadUrl((HWND)handler->GetInt(), url->GetString().ToWString()); } else if (methodName == L"reload"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; jb::reload((HWND)handler->GetInt()); } //// (true|false,[handler]);// 允许进行拖动 //extensionCode << "JWebTop.=function(enable,handler){JWebTop.cefQuery({m:'enableDrag',enable:enable,handler:(handler?handler:JWebTop.handler)})};" << endl; //// ([handler]);// 开始进行拖动 //extensionCode << "JWebTop.=function(handler){JWebTop.cefQuery({m:'startDrag',handler:(handler?handler:JWebTop.handler)})};" << endl; //// ([handler]);// 停止拖动 //extensionCode << "JWebTop.=function(handler){JWebTop.cefQuery({m:'stopDrag',handler:(handler?handler:JWebTop.handler)})};" << endl; else if (methodName == L"enableDrag"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; CefRefPtr<CefValue> enable = value->GetValue("enable"); if (enable == NULL)return false; jb::enableDrag((HWND)handler->GetInt(), enable->GetBool()); } else if (methodName == L"startDrag"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; jb::startDrag((HWND)handler->GetInt()); } else if (methodName == L"stopDrag"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; jb::stopDrag((HWND)handler->GetInt()); } else if (methodName == L"reloadIgnoreCache"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; jb::stopDrag((HWND)handler->GetInt()); } else if (methodName == L"runApp"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; CefRefPtr<CefValue> app = value->GetValue("app"); CefRefPtr<CefValue> parentWin = value->GetValue("parentWin"); jb::runApp((HWND)handler->GetInt(), app->GetString().ToWString(), parentWin == NULL ? 0 : parentWin->GetInt() ,NULL,NULL,NULL,-1,-1,-1,-1); } else if (methodName == L"runAppMore"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; CefRefPtr<CefValue> app = value->GetValue("app"); CefRefPtr<CefValue> parentWin = value->GetValue("parentWin"); CefRefPtr<CefValue> url = value->GetValue("url"); CefRefPtr<CefValue> title = value->GetValue("title"); CefRefPtr<CefValue> icon = value->GetValue("icon"); CefRefPtr<CefValue> x = value->GetValue("x"); CefRefPtr<CefValue> y = value->GetValue("y"); CefRefPtr<CefValue> w = value->GetValue("w"); CefRefPtr<CefValue> h = value->GetValue("h"); jb::runApp((HWND)handler->GetInt(), app->GetString().ToWString(), parentWin == NULL ? 0 : parentWin->GetInt() , (url == NULL ? NULL : LPTSTR(url->GetString().ToWString().c_str())) , (title == NULL ? NULL : LPTSTR(title->GetString().ToWString().c_str())) , (icon == NULL ? NULL : LPTSTR(icon->GetString().ToWString().c_str())) , (x == NULL ? -1 : x->GetInt()) , (y == NULL ? -1 : y->GetInt()) , (w == NULL ? -1 : w->GetInt()) , (h == NULL ? -1 : h->GetInt())); } else if(methodName == L"close"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; jb::close((HWND)handler->GetInt()); } else if (methodName == L"showDev"){ CefRefPtr<CefValue> handler = value->GetValue("handler"); if (handler == NULL)return false; jb::showDev((HWND)handler->GetInt()); } else{ return false; } return true; }
bool FUnrealCEFSubProcessRemoteScripting::HandleDeleteValueMessage(CefRefPtr<CefBrowser> Browser, CefRefPtr<CefListValue> MessageArguments) { CefRefPtr<CefFrame> MainFrame = Browser->GetMainFrame(); CefRefPtr<CefV8Context> Context = MainFrame->GetV8Context(); ScopedV8Context ContextScope(Context); CefRefPtr<CefV8Value> RootObject = Context->GetGlobal()->GetValue("ue"); if (!RootObject.get()) { // The root object should always be created on context creation. return false; } for (size_t I = 0; I < MessageArguments->GetSize(); I++) { if (MessageArguments->GetType(I) != VTYPE_DICTIONARY) { return false; } CefRefPtr<CefDictionaryValue> Argument = MessageArguments->GetDictionary(I); if (Argument->GetType("name") != VTYPE_STRING || Argument->GetType("id") != VTYPE_STRING || Argument->GetType("permanent") != VTYPE_BOOL) { // Wrong message argument types or count return false; } CefString Name = Argument->GetString("name"); CefString Id = Argument->GetString("id"); bool bPermanent = Argument->GetBool("permanent"); FGuid Guid; if (!FGuid::Parse(Id.ToWString().c_str(), Guid)) { return false; } if (bPermanent) { int32 BrowserID = Browser->GetIdentifier(); CefRefPtr<CefDictionaryValue> Bindings; if (PermanentBindings.Contains(BrowserID)) { Bindings = PermanentBindings[BrowserID]; if (!Bindings->HasKey(Name)) { return false; } if (Guid.IsValid()) { CefRefPtr<CefDictionaryValue> CefValue = Bindings->GetDictionary(Name); if (CefValue.get() && CefValue->GetString("$id") != Id) { return false; } } Bindings->Remove(Name); } } if (!RootObject->HasValue(Name)) { return false; } if (Guid.IsValid()) { CefRefPtr<CefV8Value> Value = RootObject->GetValue(Name); if (!Value->HasValue("$id") || !Value->GetValue("$id")->IsString() || Value->GetValue("$id")->GetStringValue() != Id) { return false; } } RootObject->DeleteValue(Name); } return true; }
// This is the client message handler. bool CaffeineClientHandler::OnProcessMessageReceived( CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) { if(message->GetName() == "popupWindow" ) { CefRefPtr<CefListValue> retval = message->GetArgumentList(); wstring msg = L"Window Creation Timing: ClientHandler popupWindow: " + retval->GetString(0).ToWString(); app->ShellLog(msg); string uuid = retval->GetString(0); string initArg = retval->GetString(1).ToString(); bool bCreateFrameless = retval->GetBool(2); int height = retval->GetInt(3); int width = retval->GetInt(4); int left = retval->GetInt(5); int top = retval->GetInt(6); string target = (retval->GetSize()>7)? retval->GetString(7) : ""; bool bResizable = (retval->GetSize()>8)? retval->GetBool(8) : true; int minWidth = retval->GetInt(9); int minHeight = retval->GetInt(10); bool windowAlreadyExists = false; if ( target == "ymail" ) { if ( mailUUID != "" ) windowAlreadyExists = true; else mailUUID = uuid; } if ( ! windowAlreadyExists ) CreateRemoteWindow(height, width, left, top, uuid, initArg, bCreateFrameless, bResizable, target, minWidth, minHeight); else ActivateWindow( uuid ); } else if(message->GetName() == "setCookie" ) { CefRefPtr<CefListValue> retval = message->GetArgumentList(); string name = retval->GetString(1); string value = retval->GetString(2); int callbackNumber = retval->GetInt(0); CefPostTask(TID_IO, NewCefRunnableFunction(IOT_Set, name, value, callbackNumber) ); } else if(message->GetName() == "toastWindow" ) { CefRefPtr<CefListValue> retval = message->GetArgumentList(); string uuid = retval->GetString(0); string initArg = retval->GetString(1).ToString(); CreateToastWindow(uuid, initArg); } #ifdef OS_WIN else if (message->GetName() == "triggerDump") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create(); crAddScreenshot2(CR_AS_VIRTUAL_SCREEN | CR_AS_USE_JPEG_FORMAT, 80); CR_EXCEPTION_INFO crDump = {0,}; crDump.cb = sizeof(CR_EXCEPTION_INFO); crDump.exctype = CR_SEH_EXCEPTION; crDump.code = 10203040; crDump.pexcptrs = NULL; if(crGenerateErrorReport(&crDump) == 0) { StatusObject->SetString("status", "success"); } else { StatusObject->SetString("status", "error"); } CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, message->GetName()); callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0)); callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } #endif else if(message->GetName() == "sendIPC") { // Probably should have a few asserts around this CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefString browser_handle = retval->GetString(0); CefRefPtr<CefFrame> frame = NULL; if (app->m_WindowHandler.find(browser_handle) != app->m_WindowHandler.end()) { // TODO: Do we really need this look up? CefRefPtr<CefBrowser> target_browser = app->m_WindowHandler[browser_handle]->GetBrowser(); if (target_browser.get()) { frame = target_browser->GetMainFrame(); if (frame != NULL && frame->IsValid()) { CefString snippet = L"Caffeine.Event.fire(Caffeine.CEFContext, 'ipcReceived', '" + (retval->GetString(2)).ToWString() + L"', unescape('" + (retval->GetString(1)).ToWString() + L"'));"; frame->ExecuteJavaScript(snippet, frame->GetURL(), 0); } } } } else if (message->GetName() == "getDownloadDirectoryFromUser") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create(); CefString DirectoryPicked; if(GetDirectoryFromUser(DirectoryPicked)) { wstring empty = wstring(L""); // TODO: What about duplicate directory paths? AcceptableDownloadDirectories.push_front(DirectoryPicked); StatusObject->SetString("status", "success"); StatusObject->SetString("downloadPath", DirectoryPicked); app->showFileSaveAsDialog = false; } else { StatusObject->SetString("status", "error"); } CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, message->GetName()); callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0)); callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } else if (message->GetName() == "getDownloadPathFromUser") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create(); CefString filename = retval->GetString(1); CefString DirectoryPicked; if(GetPathFromUser(filename, DirectoryPicked)) { // TODO: What about duplicate directory paths? wstring empty = wstring(L""); AcceptableDownloadDirectories.push_front(DirectoryPicked); StatusObject->SetString("status", "success"); StatusObject->SetString("downloadPath", DirectoryPicked); StatusObject->SetString("filename", filename); app->showFileSaveAsDialog = false; } else { StatusObject->SetString("status", "error"); } CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, message->GetName()); callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0)); callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } else if (message->GetName() == "resetDownloadDirectory") { SetDownloadPath(L""); CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create(); StatusObject->SetString("status", "success"); app->showFileSaveAsDialog = true; CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, message->GetName()); callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0)); callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } else if (message->GetName() == "getDownloadPath") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create(); StatusObject->SetString("status", "success"); app->showFileSaveAsDialog = false; StatusObject->SetString("downloadPath", GetDownloadPath(L"")); CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, message->GetName()); callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0)); callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } else if (message->GetName() == "setDownloadPath") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefRefPtr<CefDictionaryValue> StatusObject = CefDictionaryValue::Create(); list<CefString>::iterator i = find(AcceptableDownloadDirectories.begin(), AcceptableDownloadDirectories.end(), retval->GetString(1)); if (i != AcceptableDownloadDirectories.end()) { StatusObject->SetString("status", "success"); app->showFileSaveAsDialog = false; SetDownloadPath(retval->GetString(1)); } else // Error case { StatusObject->SetString("status", "error"); app->showFileSaveAsDialog = true; } CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, message->GetName()); callbackMsg->GetArgumentList()->SetInt(1, retval->GetInt(0)); callbackMsg->GetArgumentList()->SetDictionary(2, StatusObject); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } else if (message->GetName() == "showDirectory") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefString directory = retval->GetString(0); list<CefString>::iterator i = find(AcceptableDownloadDirectories.begin(), AcceptableDownloadDirectories.end(), directory); if (i != AcceptableDownloadDirectories.end()) { if(retval->GetType(1) == VTYPE_LIST) { CefRefPtr<CefListValue> selected_files = retval->GetList(1); // Probably could have just one function ShowFolders that checks the type of the second arg. ShowFolder2(directory.ToWString(), selected_files); } else // It's a string { CefString selected_file = retval->GetString(1); ShowFolder(directory.ToString(), selected_file); } } else { app->ShellLog(L"showDirectory called BUT no AcceptableDownloadDirectories value found"); } } else if (message->GetName() == "startFlashing") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefString browser_handle = retval->GetString(0); bool bAutoStop = retval->GetBool(1); StartFlashing(browser_handle, bAutoStop); } else if(message->GetName() == "stopFlashing") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefString browser_handle = retval->GetString(0); StopFlashing(browser_handle); } else if(message->GetName() == "activateWindow") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefString browser_handle = retval->GetString(0); ActivateWindow(browser_handle); } else if(message->GetName() == "activateApp") { #ifdef __APPLE__ activatesApp(); #endif } else if(message->GetName() == "showWindow") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefString uuid = retval->GetString(0); ShowWindow(uuid); // TODO: Should probably handle this event from JS CreateAndDispatchCustomEvent("show"); } else if(message->GetName() == "hideWindow") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefString uuid = retval->GetString(0); HideWindow(uuid); // TODO: Should probably handle this event from JS CreateAndDispatchCustomEvent("hide"); } else if (message->GetName() == "setUserAgent") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); CefString UA = retval->GetString(0); user_agent = UA; } else if (message->GetName() == "setPrefixMapping") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); requestPrefixMap[retval->GetString(0)] = retval->GetString(1); } #ifdef ENABLE_MUSIC_SHARE else if (message->GetName() == "ITunesPlayPreview") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); wstring url = retval->GetString(0); ITunesPlayPreview(url); } #if defined(OS_WIN) else if (message->GetName() == "isITunesOn") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); string name = message->GetName(); int retvalInt = retval->GetInt(0); CefRefPtr<CefDictionaryValue> isOn = CefDictionaryValue::Create(); isITunesOn(isOn); CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, name); callbackMsg->GetArgumentList()->SetInt(1, retvalInt); callbackMsg->GetArgumentList()->SetDictionary(2, isOn); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } else if (message->GetName() == "getITunesTrackInfo") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); string name = message->GetName(); int retvalInt = retval->GetInt(0); CefRefPtr<CefDictionaryValue> TrackInfo = CefDictionaryValue::Create(); getITunesTrackInfo(TrackInfo); CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, name); callbackMsg->GetArgumentList()->SetInt(1, retvalInt); callbackMsg->GetArgumentList()->SetDictionary(2, TrackInfo); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } else if (message->GetName() == "getInstalledPlayers") { ShellLog(L"FLAME CHART CaffeineClientHandler.getInstalledPlayers"); CefRefPtr<CefListValue> retval = message->GetArgumentList(); string name = message->GetName(); int retvalInt = retval->GetInt(0); CefRefPtr<CefDictionaryValue> InstalledPlayers = CefDictionaryValue::Create(); getInstalledPlayers(InstalledPlayers); CefRefPtr<CefProcessMessage> callbackMsg = CefProcessMessage::Create("invokeCallback"); callbackMsg->GetArgumentList()->SetString(0, name); callbackMsg->GetArgumentList()->SetInt(1, retvalInt); callbackMsg->GetArgumentList()->SetDictionary(2, InstalledPlayers); browser->SendProcessMessage(PID_RENDERER, callbackMsg); } #else //OS_MAC else if (message->GetName() == "isITunesOn") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); string name = message->GetName(); int retvalInt = retval->GetInt(0); isITunesOn(name, retvalInt); } else if (message->GetName() == "getITunesTrackInfo") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); string name = message->GetName(); int retvalInt = retval->GetInt(0); getITunesTrackInfo(name, retvalInt); } else if (message->GetName() == "getInstalledPlayers") { ShellLog(L"FLAME CHART CaffeineClientHandler.getInstalledPlayers"); CefRefPtr<CefListValue> retval = message->GetArgumentList(); string name = message->GetName(); int retvalInt = retval->GetInt(0); getInstalledPlayers(name, retvalInt); } #endif //OS_WIN #endif //ENABLE_MUSIC_SHARE else if (message->GetName() == "shakeWindow") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); ASSERT(retval->GetSize() == 1); string uuid = retval->GetString(0); #ifdef __APPLE__ ShakeWindow(uuid); #endif } else if (message->GetName() == "moveWindowTo") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); ASSERT(retval->GetSize() == 5); string uuid = retval->GetString(0); int left = retval->GetInt(1); int top = retval->GetInt(2); int height = retval->GetInt(3); int width = retval->GetInt(4); MoveOrResizeWindow(uuid, left, top, height, width); } // This needs to be broken up into two functions: one to determine if a // window is the foreground window and another to pop up notifications. else if(message->GetName() == "messageReceived") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); wstring from = retval->GetString(0); wstring display = retval->GetString(1); wstring msg = retval->GetString(2); wstring convId = retval->GetString(3); MessageReceived(from, display, msg, convId); } else if(message->GetName() == "stateIsNowLoggedIn") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); stateIsNowLoggedIn(retval->GetBool(0)); } else if(message->GetName() == "enableSessionMenus") { #ifdef OS_MACOSX CefRefPtr<CefListValue> retval = message->GetArgumentList(); enableSessionMenus(retval->GetBool(0)); #endif } else if (message->GetName() == "openFile") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); wstring path = retval->GetString(0); if (downloadedFiles.find(path) != downloadedFiles.end()) { OpenFile(path); } else { wstringstream msg; msg << L"Attempt made to open file '"; msg << path; msg << L"' that was not downloaded by the client"; app->ShellLog(msg.str()); } } #ifdef OS_MACOSX else if(message->GetName() == "setBadgeCount") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); ChangeBadgeCount(retval->GetInt(0), retval->GetBool(1)); } else if(message->GetName() == "showViewMenu") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); ShowViewMenu(retval->GetBool(0)); } else if(message->GetName() == "setUserToken") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); string usr = retval->GetString(0); string tok = retval->GetString(1); SetUserToken(usr,tok); } else if(message->GetName() == "removeAllUserTokens" ) { RemoveAllTokens(); } else if(message->GetName() == "removeUserToken") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); string usr = retval->GetString(0); RemoveUserToken(usr); } #endif #ifdef OS_WIN else if (message->GetName() == "restartApplication") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); RestartApplication(retval->GetString(0)); } else if (message->GetName() == "setEphemeralState") { CefRefPtr<CefListValue> retval = message->GetArgumentList(); SetEphemeralState(retval->GetString(0)); } #endif else if (message->GetName() == "setBrowserValue") { CefRefPtr<CefListValue> args = message->GetArgumentList(); switch (args->GetInt(0)) { case SET_BROWSER_VALUE_FEEDBACK_LINK: #ifdef __APPLE__ setFeedbackLink( args->GetString(1).ToString()); #endif break; } } #ifdef __APPLE__ #pragma mark === RTT2 Sockets - browser side === else if ( message->GetName() == "createSocket" ) { createSocket(message->GetArgumentList()); } else if ( message->GetName() == "writeSocket" ) { writeToSocket(message->GetArgumentList()); } else if ( message->GetName() == "closeSocket" ) { closeSocket(message->GetArgumentList()->GetInt(0)); } #endif return false; }