#include "stdafx.h" #if (defined _WIN32 || defined _WIN64) #include #include #include #include #include "chromelink_export.h" #pragma comment(lib, "cefControl.lib") #else #include #endif #include "fileutil.h" #include "baseEx.h" #include "CWebsocketServer.h" #include "mod_chromium.h" #include "base64.h" #include "CModTools.h" #include "cJSON.h" #include "SpIni.h" #include "CSocketClient.h" #include "processControl.h" #include #include #include "../mod_upload/Upload_client_g.h" #include #include #include #include "EventCode.h" #ifdef OPEN_PERF #include #endif // OPEN_PERF #include #include "../mod_ResourceWatcher/ResourceWatcher_msg_g.h" #include "../mod_guiconsole/GUIConsole_client_g.h" #include "CommEntityUtil.hpp" #define COMPKEY_TERMINATE ((UINT_PTR) 0) #define COMPKEY_STATUS ((UINT_PTR) 1) #define COMPKEY_JOBOBJECT ((UINT_PTR) 2) void DbgByCefControl(const char * strMethod, const char* buf) { #if defined(_MSC_VER) doWithDebugModeData(strMethod, buf); #endif //_MSC_VER } namespace Chromium { void ChromiumSession::Handle_OpenBrowser(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->OpenBrowser(ctx); } void ChromiumSession::Handle_CloseBrowser(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->CloseBrowser(ctx); } void ChromiumSession::Handle_OpenCommonPage(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->OpenCommonPage(ctx); } void ChromiumSession::Handle_CloseCommonPage(SpReqAnsContext::Pointer ctx) { DbgToBeidou(ctx->link, __FUNCTION__)(); m_pEntity->CloseCommonPage(ctx); } CChromiumEntity::CChromiumEntity() :m_pWsServer(NULL), m_pTimerListener(NULL) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CChromiumEntity constructor"); //boost::thread(boost::bind(&CChromiumEntity::CefClintNotify, this)).detach(); //后台自动运行 } CChromiumEntity::~CChromiumEntity() { if (NULL != m_pWsServer) { delete m_pWsServer; m_pWsServer = NULL; } //DeleteCriticalSection(&g_csInvokFreeRDP); } #if (defined _WIN32 || defined _WIN64) void CChromiumEntity::JobNotify() { TCHAR sz[2000] = _T(""); BOOL fDone = FALSE; while (!fDone) { DWORD dwBytesXferred; ULONG_PTR CompKey; LPOVERLAPPED po; GetQueuedCompletionStatus(m_hIOCP, &dwBytesXferred, &CompKey, &po, INFINITE); fDone = (CompKey == COMPKEY_TERMINATE); if (CompKey == COMPKEY_JOBOBJECT) { switch (dwBytesXferred) { case JOB_OBJECT_MSG_END_OF_JOB_TIME: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Job time limit reached"); break; case JOB_OBJECT_MSG_END_OF_PROCESS_TIME: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Job process (Id=%d) time limit reached", po); break; case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Too many active processes in job"); break; case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Job contains no active processes"); break; case JOB_OBJECT_MSG_NEW_PROCESS: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("New process (Id=%d) in Job", po); break; case JOB_OBJECT_MSG_EXIT_PROCESS: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Process (Id=%d) terminated", po); break; case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Process (Id=%d) terminated abnormally", po); break; case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Process (Id=%d) exceeded memory limit", po); break; case JOB_OBJECT_MSG_JOB_MEMORY_LIMIT: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Process (Id=%d) exceeded job memory limit", po); break; default: DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Unknown notification: %d", dwBytesXferred); break; } CompKey = 1; } } } #endif void CChromiumEntity::OpenCommonPage(SpReqAnsContext::Pointer ctx) { auto openCommonPageThread = [this](SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); boost::unique_lock commonPageLock(m_commonPageLock); std::string strTitle = ctx->Req.title.GetData(); std::string strUrl = ctx->Req.url.GetData(); int width = ctx->Req.width; int height = ctx->Req.height; int point_x = ctx->Req.point_x; int point_y = ctx->Req.point_y; std::string strTop = ctx->Req.top.GetData(); #ifdef RVC_OS_WIN auto ret = CModTools::get_mutable_instance().startCommonPage(strTitle, strUrl, width, height, point_x, point_y, strTop); #else auto srcPids = getUosBrowserPIDs(CModTools::get_mutable_instance().getUosBrowser()); auto ret = CModTools::get_mutable_instance().startCommonPage(strTitle, strUrl, width, height, point_x, point_y, strTop); std::this_thread::sleep_for(std::chrono::seconds(2)); auto dstPids = getUosBrowserPIDs(CModTools::get_mutable_instance().getUosBrowser()); if (ConfigManager::getInstance().m_commonPageArr.find(strTitle) == ConfigManager::getInstance().m_commonPageArr.end()) { std::vector tmp; ConfigManager::getInstance().m_commonPageArr[strTitle] = tmp; } std::vector difference; // 使用 std::set_difference 查找差值 std::set_difference(dstPids.begin(), dstPids.end(), srcPids.begin(), srcPids.end(), std::back_inserter(difference)); /* for (auto it : srcPids) DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("srcPids %d", it); for (auto it : dstPids) DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("dstPids %d", it); */ for (auto it : difference) { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("open commonPage %d", it); ConfigManager::getInstance().m_commonPageArr[strTitle].push_back(it); } #endif ctx->Answer(ret.first, ret.first); }; std::thread(openCommonPageThread, ctx).detach(); } void CChromiumEntity::CloseCommonPage(SpReqAnsContext::Pointer ctx) { auto closePage = [this](SpReqAnsContext::Pointer ctx) { LOG_FUNCTION(); boost::unique_lock commonPageLock(m_commonPageLock); std::string strName = ctx->Req.title.GetData(); #ifdef RVC_OS_WIN CModTools::get_mutable_instance().stopCommonPage(strName); std::this_thread::sleep_for(std::chrono::seconds(1)); CModTools::get_mutable_instance().stopCommonPage(strName); #else if (ConfigManager::getInstance().m_commonPageArr.find(strName) != ConfigManager::getInstance().m_commonPageArr.end()) { auto arr = ConfigManager::getInstance().m_commonPageArr[strName]; for (auto it : arr) { CSimpleStringA cmd = CSimpleStringA::Format("sudo kill -9 %d", it); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("CloseCommonPage %s", cmd.GetData()); system(cmd.GetData()); } arr.clear(); ConfigManager::getInstance().m_commonPageArr[strName] = arr; } std::this_thread::sleep_for(std::chrono::seconds(1)); #endif // RVC_OS_WIN ctx->Answer(ErrorCodeEnum::Error_Succeed); startupPageClean(); }; std::thread(closePage, ctx).detach(); } void CChromiumEntity::CloseBrowser(SpReqAnsContext::Pointer ctx) { CSimpleString strType = ctx->Req.type; CSimpleString strNmae = ctx->Req.name; DbgToBeidou(ctx->link, "CloseBrowser")(); if (!strType.Compare((+ERR_PAGE_REASON::OutsideRequest)._to_string(), true)) { CModTools::get_mutable_instance().StopSingleChromiumBrowserByName((+ERR_PAGE_REASON::OutsideRequest)._to_string()); ctx->Answer(ErrorCodeEnum::Error_Succeed); } else if (!strType.Compare((+ERR_PAGE_REASON::SpecialPageFromOtherEntity)._to_string(), true)) { CSimpleStringA dstBrowserName = strType + "_" + strNmae; CModTools::get_mutable_instance().StopSingleChromiumBrowserByName(dstBrowserName.GetData()); ctx->Answer(ErrorCodeEnum::Error_Succeed); } else { ctx->Answer(ErrorCodeEnum::Error_NoTarget); } } void CChromiumEntity::OpenBrowser(SpReqAnsContext::Pointer ctx) { std::shared_ptr CleanParamFun((void*)0, [&](void*) { CModTools::get_mutable_instance().SetSpecialPageParam("", "", "", 0); }); CSimpleStringA strType = ctx->Req.type; DbgToBeidou(ctx->link, "OpenBrowser")(); if (!strType.Compare((+ERR_PAGE_REASON::OutsideRequest)._to_string(), true)) { CSimpleStringA strUrl = ctx->Req.mainUrl, strUrl2 = ctx->Req.viceUrl; if (strUrl.IsNullOrEmpty()) { ctx->Answer(Error_Param); return; } auto ret = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::OutsideRequest, std::make_tuple(strUrl.GetData(), strUrl2.GetData())); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open OutsideRequest browser page %s return %d", (LPCTSTR)strUrl, ret.first); ctx->Answer(ret.first); } else if (!strType.Compare((+ERR_PAGE_REASON::SpecialPageFromOtherEntity)._to_string(), true)) { CSimpleStringA strUrl = ctx->Req.mainUrl, strUrl2 = ctx->Req.viceUrl, sizeParam = ctx->Req.param1 , pointParam = ctx->Req.param2, browserName = ctx->Req.name; CSimpleStringA dstBrowserName = strType + "_" + browserName; int browserTopZ = ctx->Req.top; CModTools::get_mutable_instance().SetSpecialPageParam(dstBrowserName.GetData(), sizeParam.GetData(), pointParam.GetData(), browserTopZ); //用一个临时变量解决,可能在高并发时有问题。 auto ret = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::SpecialPageFromOtherEntity, std::make_tuple(strUrl.GetData(), strUrl2.GetData())); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open %s browser page %s return %d", dstBrowserName.GetData(), (LPCTSTR)strUrl, ret.first); ctx->Answer(ret.first); } else ctx->Answer(ErrorCodeEnum::Error_NoTarget); } void CChromiumEntity::OnPaused() { #ifdef OPEN_PERF ProfilerStop();//停止性能分析 #endif // OPEN_PERF } void CChromiumEntity::OnPreStart_Init(CAutoArray& strArgs, CSmartPointer& pTransactionContext) { LogManager::getInstance().logEntityStageChange("OnPreStart_Init", 0, "begin"); #ifdef OPEN_PERF auto profStr = CSimpleString::Format("chromiumAnalyze_%s.prof", generateTimeStr(true).c_str()); std::thread([](std::string str) { ProfilerStart(str.c_str());//开启性能分析 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Generate chromiumAnalyze, %s", str.c_str()); }, profStr.GetData()).detach(); #endif // OPEN_PERF //init the chrome params from centersetting FetchCustomMainUrl(strArgs); CModTools::get_mutable_instance().InitCModTools(this); #if (defined _WIN32 || defined _WIN64) const int ArgsCount = strArgs.GetCount(); LOG_TRACE("strArgs.GetCount() = %d", ArgsCount); for (int i = 0; i < ArgsCount; ++i) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("strArgs[%d] = %s", i, strArgs[i].GetData()); } if (ArgsCount == 1) { ConfigManager::getInstance().m_strCustomMainUrl = strArgs[0].GetData(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Get custom main ulr: %s", ConfigManager::getInstance().m_strCustomMainUrl.c_str()); } else if (ArgsCount == 2) { ConfigManager::getInstance().m_strCustomMainUrl = strArgs[0].GetData(); ConfigManager::getInstance().m_strCustomAdUrl = strArgs[1].GetData(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Get custom main url: %s, ad url: %s" , ConfigManager::getInstance().m_strCustomMainUrl.c_str(), ConfigManager::getInstance().m_strCustomAdUrl.c_str()); } #endif GetFunction()->GetSystemStaticInfo(ConfigManager::getInstance().getSysInfo()); if (!IsConfigMode()) { CSmartPointer spConfig; if (Error_Succeed == GetFunction()->OpenConfig(Config_CenterSetting, spConfig))//特别坑,这个OpenConfig返回一直都是success { auto webMaskKey = CSimpleString::Format("WebMask_%s", ConfigManager::getInstance().getSysInfo().strMachineType.GetData()); CSimpleString webMaskStr; bool no_startup = false; ConfigManager::getInstance().m_withBrowser = false; if (Error_Succeed == spConfig->ReadConfigValue("Chromium", webMaskKey.GetData(), webMaskStr)) { auto maskArr = webMaskStr.Split('|'); for (int i = 0; i < maskArr.GetCount(); i++) { auto trimStr = maskArr[i].Trim(); if (!trimStr.Compare("ad", true))//will open ad browser ConfigManager::getInstance().m_runAd = true; else if (!trimStr.Compare("main", true))//will open main browser ConfigManager::getInstance().m_runMain = true; else if (!trimStr.Compare("extend", true))//will open extend browser ConfigManager::getInstance().m_runExtend = true; else if (!trimStr.Compare("login", true))//will open login(User Desktop) browser ConfigManager::getInstance().m_runLogin = true; else if (!trimStr.Compare("with_browser", true))//will not open any browser ConfigManager::getInstance().m_withBrowser = true; else if (!trimStr.Compare("with_min", true))//the errPage contains min button ConfigManager::getInstance().m_withMin = true; else if (!trimStr.Compare("with_close", true))//the errPage contains close button ConfigManager::getInstance().m_withClose = true; else if (!trimStr.Compare("with_debugmode", true))//the browser will open remote control function ConfigManager::getInstance().m_withDebugMode = true; else if (!trimStr.Compare("with_magic", true))//the browser will open special queue for log sender. ConfigManager::getInstance().m_withMagic = true; else if (!trimStr.Compare("with_media", true))//the browser will support media play and RTC function ConfigManager::getInstance().m_withMedia = true; else if (!trimStr.Compare("with_unsafe_ad", true)) ConfigManager::getInstance().m_withUnsafeAd = true; else if (!trimStr.Compare("with_unsafe_main", true)) ConfigManager::getInstance().m_withUnsafeMain = true; else if (!trimStr.Compare("with_specialTest", true))//chromium will run specical test ConfigManager::getInstance().m_withSpecialTest = true; else if (!trimStr.Compare("with_LinkLog", true))//control do_sendJson to print more logs(request) ConfigManager::getInstance().m_withLinkLog = true; else if (!trimStr.Compare("with_nofilelog", true))//DbgEx do not print logs to local storage, but DbgEx() is discard. ConfigManager::getInstance().m_withNoFileLog = true; else if (!trimStr.Compare("with_console", true))//control browser will print console logs ConfigManager::getInstance().m_withConsole = true; else if (!trimStr.Compare("no_startup", true))//control browser will print console logs no_startup = true; else if (!trimStr.Compare("sogou_force", true))//force click setfocus page every time ConfigManager::getInstance().setSogouForce(1); else if (!trimStr.Compare("sogou_no", true))//not adapt to sogou ConfigManager::getInstance().setSogouForce(2); } CSmartPointer chromiumCfg; if (ConfigManager::getInstance().m_runMain == true && Error_Succeed == GetFunction()->OpenConfig(Config_Cache, chromiumCfg)) chromiumCfg->WriteConfigValueInt("Run", "no_startup", no_startup ? 1 : 0); #if (defined _WIN32 || defined _WIN64) #else //对于UOS来说,没有最小化和关闭按钮 ConfigManager::getInstance().m_withMin = false; ConfigManager::getInstance().m_withClose = false; #endif CSimpleString msg = CSimpleString::Format("MachineType: %s, find %s, readStr:%s, m_runAd:%d, m_runMain:%d, m_runExtend:%d, m_runLogin:%d, \ m_withBrowser:%d, with_min:%d, with_close:%d, m_withDebugMode:%d, m_withMagic:%d, m_withNoFileLog:%d, m_withMedia:%d, m_withSpecialTest:%d, m_withConsole:%d, m_withLinkLog:%d", ConfigManager::getInstance().getSysInfo().strMachineType.GetData(), webMaskKey.GetData(), webMaskStr.GetData(), ConfigManager::getInstance().m_runAd, ConfigManager::getInstance().m_runMain, ConfigManager::getInstance().m_runExtend, ConfigManager::getInstance().m_runLogin, ConfigManager::getInstance().m_withBrowser, ConfigManager::getInstance().m_withMin, ConfigManager::getInstance().m_withClose, ConfigManager::getInstance().m_withDebugMode, ConfigManager::getInstance().m_withMagic, ConfigManager::getInstance().m_withNoFileLog, ConfigManager::getInstance().m_withMedia, ConfigManager::getInstance().m_withSpecialTest, ConfigManager::getInstance().m_withConsole, ConfigManager::getInstance().m_withLinkLog); LogManager::getInstance().logEntityStatus(msg.GetData(), LOG_LEVEL_INFO, 0, "none"); /* DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("MachineType: %s, find %s, readStr:%s, m_runAd:%d, m_runMain:%d, m_runExtend:%d, m_runLogin:%d, \ m_withBrowser:%d, with_min:%d, with_close:%d, m_withDebugMode:%d, m_withMagic:%d, m_withNoFileLog:%d, m_withMedia:%d, m_withSpecialTest:%d, m_withConsole:%d, m_withLinkLog:%d", m_sysInfo.strMachineType.GetData(), webMaskKey.GetData(), webMaskStr.GetData(), m_runAd, m_runMain, m_runExtend, m_runLogin, m_withBrowser ,m_withMin, m_withClose, m_withDebugMode, m_withMagic, m_withNoFileLog, m_withMedia, m_withSpecialTest, m_withConsole, m_withLinkLog); */ int forceCacheClean = false; if (Error_Succeed == spConfig->ReadConfigValueInt("Chromium", "forceCacheClean", forceCacheClean) && forceCacheClean) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("forceCacheClean, call OnOnBrowserCacheClean"); ResourceWatcher::BrowserCacheClean evt; evt.needClean = 1; OnBrowserCacheClean(NULL, 0, 0, evt); } } else DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("can not find %s, use default", webMaskKey.GetData()); } CSimpleString ExtensionsParam = ""; if (Error_Succeed == spConfig->ReadConfigValue("Chromium", "ExtensionsParam", ExtensionsParam) && ExtensionsParam.GetLength() > 0) { CSimpleString msg = CSimpleString::Format("ExtensionsParam:%s", ExtensionsParam.GetData()); LogManager::getInstance().logEntityStatus(msg.GetData(), LOG_LEVEL_INFO, 0, "none"); auto paramArr = ExtensionsParam.Split('|'); for (int i = 0; i < paramArr.GetCount(); i++) { auto trimStr = paramArr[i].Trim(); if (!trimStr.Compare("Debug", true))//browser can be control right menu ConfigManager::getInstance().m_extension_debugOpen = true; else if (!trimStr.Compare("header_Terminalno", true)) { ConfigManager::getInstance().m_extension_withTerminal = true; ConfigManager::getInstance().m_extension_headerStr = CSimpleString::Format("%s:%s", HEADER_TERMINALNO_NAME, ConfigManager::getInstance().getSysInfo().strTerminalID).GetData(); } } } if (!ConfigManager::getInstance().m_runAd && !ConfigManager::getInstance().m_runMain && !ConfigManager::getInstance().m_runExtend && !ConfigManager::getInstance().m_withBrowser) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("can not open centerSetting, maybe fault"); } #ifdef RVC_OS_WIN if (ConfigManager::getInstance().m_withMagic) { std::string magicStr = CModTools::get_mutable_instance().getMagicStr(); boost::thread(boost::bind(SaveCefclientLog, magicStr)).detach(); } #endif } if (ConfigManager::getInstance().m_withSpecialTest) { auto repeat_dirtyLogs_Fun = [] { int count = 0; while (true) { std::string dirtyLog = std::to_string(count++) + std::string(100 + count, 0xcd); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("dirty_logs")(dirtyLog.c_str()); //std::this_thread::sleep_for(std::chrono::seconds(3)); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } }; #ifdef DEVOPS_ON_ST std::thread(repeat_dirtyLogs_Fun).detach(); #elif defined(DEVOPS_ON_UAT)/*DevOps流水线编译,UAT环境*/ std::thread(repeat_dirtyLogs_Fun).detach(); #endif // DEVOPS } LogManager::getInstance().logEntityStageChange("OnPreStart_Init", 0, "end"); } bool CChromiumEntity::OnPreStart_socketStart(CAutoArray& strArgs, CSmartPointer& pTransactionContext) { LogManager::getInstance().logEntityStageChange("OnPreStart_socketStart", 0, "begin"); ErrorCodeEnum Error; if (Error_Succeed != (Error = GetFunction()->StartTcpBridgeServer(ConfigManager::getInstance().getTcpBridgePort()))) { LogManager::getInstance().logEntityStageChange("OnPreStart_socketStart", 2, "end", Error_Unexpect, "start tcp bridge server failed!"); pTransactionContext->SendAnswer(Error); return false; } // load all struct define xml & start websocket server CSimpleStringA strStructPath, strExtensionPath; GetFunction()->GetPath("Base", strStructPath); strExtensionPath = strStructPath; strStructPath.Append(CSimpleStringA(SPLIT_SLASH_STR) + "res" + SPLIT_SLASH_STR + "StructConfig" + SPLIT_SLASH_STR); strExtensionPath.Append(CSimpleStringA(SPLIT_SLASH_STR) + "res" + SPLIT_SLASH_STR + "VTMModifyHeaders"); ConfigManager::getInstance().m_extensionPath = strExtensionPath.GetData(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("find struct config files in path %s", strStructPath.GetData()); m_pWsServer = new CWebsocketServer(strStructPath, this); m_pWsServer->run(); LogManager::getInstance().logEntityStageChange("OnPreStart_socketStart", 0, "end"); return true; } bool CChromiumEntity::OnPreStart_register(CAutoArray& strArgs, CSmartPointer& pTransactionContext) { LogManager::getInstance().logEntityStageChange("OnPreStart_register", 0, "begin"); ErrorCodeEnum Error; if (!ConfigManager::getInstance().m_withBrowser) { if (Error_Succeed == (Error = GetFunction()->SubscribeLog(m_uuidAccessAuth, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "AccessAuthorization"))) LogManager::getInstance().logEntityStatus("订阅AccessAuthorization消息成功", LOG_LEVEL_INFO, 0, "none"); else LogManager::getInstance().logEntityStatus("订阅AccessAuthorization消息失败", LOG_LEVEL_ERROR, 2, "none", Error, ""); if (Error_Succeed == (Error = GetFunction()->SubscribeBroadcast("ResourceWatcher", NULL, this, m_uuidResourceWatch))) LogManager::getInstance().logEntityStatus("订阅ResourceWatcher广播成功", LOG_LEVEL_INFO, 0, "none"); else LogManager::getInstance().logEntityStatus("订阅ResourceWatcher广播失败", LOG_LEVEL_ERROR, 2, "none", Error, ""); if (Error_Succeed != (Error = GetFunction()->RegistSysVarEvent("UIState", this))) LogManager::getInstance().logEntityStatus("订阅消息UIState失败", LOG_LEVEL_ERROR, 2, "none", Error, "RegistSysVarEvent UIState failed!"); if (Error_Succeed != (Error = GetFunction()->RegistSysVarEvent("TerminalStage", this))) LogManager::getInstance().logEntityStatus("订阅消息TerminalStage失败", LOG_LEVEL_ERROR, 2, "none", Error, "RegistSysVarEvent TerminalStage failed!"); if (Error_Succeed != (Error = GetFunction()->RegistSysVarEvent("CardStoreInUse", this))) LogManager::getInstance().logEntityStatus("订阅消息CardStoreInUse失败", LOG_LEVEL_ERROR, 2, "none", Error, "RegistSysVarEvent CardStoreInUse failed!"); } LogManager::getInstance().logEntityStageChange("OnPreStart_register", 0, "end"); return true; } bool CChromiumEntity::OnPreStart_openWeb() { LogManager::getInstance().logEntityStageChange("OnPreStart_openWeb", 0, "begin"); if (ConfigManager::getInstance().m_runExtend) openExtendPage(); if (!ConfigManager::getInstance().m_runMain)//不启动页面 return true; do { CSimpleStringA t_terminalState; ErrorCodeEnum rc = ErrorCodeEnum::Error_Succeed; if ((rc = GetFunction()->GetSysVar("TerminalStage", t_terminalState)) != ErrorCodeEnum::Error_Succeed) { LogManager::getInstance().logEntityStatus("读取TerminalStage失败,可能不存在", LOG_LEVEL_ERROR, 2, "none", rc, ""); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("%s read TerminalStage Error %d, maybe not exist", __FUNCTION__, rc); break; } else if ('A' != t_terminalState[0] && 'Z' != t_terminalState[0]) { if (ConfigManager::getInstance().m_withBrowser) break;//run IEBrowser if ('X' == t_terminalState[0]) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("do not begin accessAuth, terminalStage X, do nothing."); break; } else if ('S' == t_terminalState[0]) { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::warnPrompt, std::tuple (ConfigManager::getInstance().getSysInfo().strTerminalID.GetData(), generateTimeStr())); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("access failed, open page warnPrompt %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } else if ('M' == t_terminalState[0]) { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::audioErr, std::tuple (ConfigManager::getInstance().getSysInfo().strTerminalID.GetData(), generateTimeStr())); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("access failed, open page audioErr %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } else { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::breakdown, std::tuple (ConfigManager::getInstance().getSysInfo().strTerminalID.GetData(), generateTimeStr())); //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("access failed, open page breakdown %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } LogManager::getInstance().logEntityStageChange("OnPreStart_openWeb", 1, "end", Error_Unexpect , CSimpleString::Format("terminalStage is %s, access failed", t_terminalState.GetData()).GetData()); return true; } else { if (ConfigManager::getInstance().m_runAd) openAdPage(); openMainPage(); #if (defined _WIN32 || defined _WIN64) if (ConfigManager::getInstance().m_withDebugMode) getNetworkInfo(L"127.0.0.1:9222", L"", &DbgByCefControl); #endif } } while (false); LogManager::getInstance().logEntityStageChange("OnPreStart_openWeb", 0, "end"); return true; } void CChromiumEntity::openMainPage() { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setLogCode("QLR0402402F0")("open main page"); #if (defined _WIN32 || defined _WIN64) generateCefclientTimer(); #else CSystemRunInfo sysruninfo; GetFunction()->GetSystemRunInfo(sysruninfo); if (!(sysruninfo.dwBootOption & SystemBootOptionEnum::BootOption_Test)) generateCefclientTimer();//非--test时,才会打开浏览器 #endif } void CChromiumEntity::openAdPage() { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::Ad); //LogManager::getInstance().logEntityOpenPage((+ERR_PAGE_REASON::Ad)._to_string(), openRet.second, openRet.first, "openPage"); } void CChromiumEntity::openExtendPage() { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::extend); //LogManager::getInstance().logEntityOpenPage((+ERR_PAGE_REASON::extend)._to_string(), openRet.second, openRet.first, "openPage"); } void CChromiumEntity::openInstallPage() { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::Install); //LogManager::getInstance().logEntityOpenPage((+ERR_PAGE_REASON::Install)._to_string(), openRet.second, openRet.first, "openPage"); } void CChromiumEntity::openStartupPage() { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::startup); //LogManager::getInstance().logEntityOpenPage((+ERR_PAGE_REASON::startup)._to_string(), openRet.second, openRet.first, "openPage"); } void CChromiumEntity::openPerformanceMonitorPage() { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::performance_monitor); //LogManager::getInstance().logEntityOpenPage((+ERR_PAGE_REASON::performance_monitor)._to_string(), openRet.second, openRet.first, "openPage"); } void CChromiumEntity::startWithCfg() { OnPreStart_Init(m_strArgs, m_pTransactionContext);//初始化部分, perf ,killchromium, signal, get custom url if (!IsConfigMode()) { if (!OnPreStart_register(m_strArgs, m_pTransactionContext)) { return; } //if contain default setting, then oepn web by setting #if (defined _WIN32 || defined _WIN64) if (m_strArgs.GetCount())//It do not contain default setting normally { if (ConfigManager::getInstance().m_strCustomMainUrl.length() > 0) openMainPage(); if (ConfigManager::getInstance().m_strCustomAdUrl.length() > 0) openAdPage(); return; } #endif if (!OnPreStart_openWeb()) { return; } } else { if (!ConfigManager::getInstance().m_existRootIni) { openInstallPage(); LogEvent(Severity_High, LOG_EVT_CHROMIUM_OPEN_INSTALLPAGE, CSimpleStringA::Format("open install page")); } } } void CChromiumEntity::OnPreStart(CAutoArray strArgs, CSmartPointer pTransactionContext) { int noStartup = 0; CSmartPointer chromiumCfg; if (Error_Succeed == GetFunction()->OpenConfig(Config_Cache, chromiumCfg)) chromiumCfg->ReadConfigValueInt("Run", "no_startup", noStartup); ConfigManager::getInstance().m_noStartupPage = (noStartup == 1); LogManager::getInstance().logEntityBegin(noStartup); setReduceSpbaseLog(0); #if defined(RVC_OS_LINUX) // clear all the browser CModTools::get_mutable_instance().killAllChromium(); DoBrowserCacheClearJob(); CSimpleStringA strDbgPath; GetFunction()->GetPath("Dbg", strDbgPath); set_traceback_path(strDbgPath.GetData()); boost::thread([]() { for (auto i = 1; i < 28; i++) { if (SIGTERM == i) signal(i, [](int signum)->void { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("receive signal:%d, closeChromium", signum); CModTools::get_mutable_instance().killAllChromiumByThread(3); CWebsocketServer::stopServer(); signal(signum, SIG_DFL); raise(signum); }); else if (SIGSEGV == i || SIGABRT == i) signal(i, &seg_signal_handler); else if (SIGPROF == i || SIGALRM == i || SIGVTALRM == i) continue; else signal(i, &normal_signal_handle); } }).detach(); #endif //all the init,register,openWeb run thread auto startFun = [&]() { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnPreStart - startFun"); // init cef logger first #if (defined _WIN32 || defined _WIN64) if (nullptr == ConfigManager::getInstance().getLogProducer()) ConfigManager::getInstance().setLogProducer(create_log_producer_storage("cefclient_logger", "0", "", "", "")); #else CSimpleString dbgPath; GetFunction()->GetPath("Dbg", dbgPath); std::string dstDbgPath = dbgPath.GetData(); dstDbgPath.append(SPLIT_SLASH_STR).append("mod_chromium"); #endif OnPreStart_Init(m_strArgs, m_pTransactionContext);//初始化部分, perf ,killchromium, signal, get custom url boost::thread(boost::bind(&CChromiumEntity::DoWithSysVarEvent, this)).detach();//用于处理sysvar,避免由于阻塞动作,导致实体卡住,lost if (!OnPreStart_socketStart(m_strArgs, m_pTransactionContext)) {//OnPreStart_socketStart()->new CWebsocketServer(strStructPath, this) 时间过长 return; } auto IsRootINIExist = [&](CSimpleStringA & path) ->bool{ CSimpleStringA csHardwareCfg(true); ErrorCodeEnum eErr = GetFunction()->GetPath("HardwareCfg", csHardwareCfg); if (eErr != Error_Succeed) { path = CSimpleStringA::Format("GetPath of HardwareCfg failed(%d)", eErr); DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get path of Run failed:%s", SpStrError(eErr)); return false; } path = csHardwareCfg + SPLIT_SLASH_STR + "root.ini"; if (ExistsFileA(path)) { return true; } else { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("root.ini(%s) is not exist.", path.GetData()); return false; } }; //if root.ini not exist CSimpleString rootIni_path; ConfigManager::getInstance().m_existRootIni = IsRootINIExist(rootIni_path); //the system info may be not complete.If the device is not install ,it can't not read the terminalNo. CSystemStaticInfo t_sysInfo; GetFunction()->GetSystemStaticInfo(t_sysInfo); if (t_sysInfo.strTerminalID.GetLength() == 0)// the machine is in install mode, hence start a simple init and open the install page { if(!ConfigManager::getInstance().m_noStartupPage) openStartupPage();//open startup page in install mode ConfigManager::getInstance().m_installMode = true; ErrorCodeEnum rc = Error_Succeed; if (Error_Succeed == (rc = GetFunction()->SubscribeLog(m_uuidVTMLoader, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "VtmLoader"))) LogManager::getInstance().logEntityStatus("订阅VtmLoader消息成功", LOG_LEVEL_INFO, 0, "none"); else LogManager::getInstance().logEntityStatus("订阅VtmLoader消息失败", LOG_LEVEL_ERROR, 2, "none", rc, ""); //if in install mode, need clear CSimpleString tmpCacheDir; if (Error_Succeed != GetFunction()->GetPath("Temp", tmpCacheDir) || tmpCacheDir.GetLength() == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnBrowserCacheClean get cache path err"); return; } #if (defined _WIN32 || defined _WIN64) auto tmpArr = find_files(tmpCacheDir.GetData(), "cefCache*", true); std::shared_ptr> tmpDirArr(new std::vector()); for each (auto it in tmpArr) tmpDirArr.get()->push_back(it); auto runCacheClean = [](std::shared_ptr> p) ->void { //CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::breakdown, true);//close all tab for each (auto it in *p.get()) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER, CSimpleStringA::Format("clear chromium browser cache %s %s", it.c_str(), RemoveDirRecursive(it.c_str()) ? "success" : "fail")); } }; runCacheClean(tmpDirArr); #else //uos 由于无guard,需要重启整个chromium实体 //CModTools::get_mutable_instance().killAllChromium(); auto tmpDirArr = find_files(tmpCacheDir.GetData(), "cefCache*", true); auto uosTmpDirArr = find_files(tmpCacheDir.GetData(), "UOSBrowser*", true); std::for_each(uosTmpDirArr.begin(), uosTmpDirArr.end(), [&](std::string tmp) { tmpDirArr.push_back(tmp); });//insert uosTmpDirArr into tmpDirArr for (auto it = tmpDirArr.begin(); it != tmpDirArr.end(); it++) LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER, CSimpleStringA::Format("clear chromium browser cache %s %s", it->c_str(), RemoveDirRecursive(it->c_str()) ? "success" : "fail")); #endif boost::this_thread::sleep_for(boost::chrono::seconds(3)); #ifdef RVC_OS_LINUX auto srcPids = getUosBrowserPIDs(CModTools::get_mutable_instance().getUosBrowser()); #endif // RVC_OS_LINUX startWithCfg();//it will open install page std::this_thread::sleep_for(std::chrono::seconds(3)); LogWarn(Severity_Low, Error_Debug, LOG_SLV_CHROMIUM_URLOPEN, "正在启动业务界面"); if (ConfigManager::getInstance().m_existRootIni && ConfigManager::getInstance().m_installMode) return;//if root.ini exist and in install mode, do not close startup page CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::startup); startupPageClean(); return; } CSimpleStringA t_terminalState; if (ErrorCodeEnum::Error_Succeed == GetFunction()->GetSysVar("TerminalStage", t_terminalState)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnPreStart TerminalStage:%s", t_terminalState.GetData()); CAutoArray strErrorCodeArr; CAutoArray strDescriptionArr; CAutoArray strRemarkArr; auto ret = GetFunction()->GetPrivilegeFunction()->GetVTMErrMsgArr(strErrorCodeArr, strDescriptionArr, strRemarkArr); if (Error_Succeed == ret) InitUserCodeToMsgTip(strErrorCodeArr, strDescriptionArr, strRemarkArr); //should not open startup page, since it is already run before. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("startWithCfg:open normal page"); startWithCfg();//属于chromium重启或者其他情况,已经初始化好配置, open main, ad and other page } else { if (!ConfigManager::getInstance().m_noStartupPage) openStartupPage();//open startup page in normal mode // startup page may open long time if(ErrorCodeEnum::Error_Succeed == GetFunction()->GetSysVar("TerminalStage", t_terminalState)) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("may open startup too long, current terminalStage:%s", t_terminalState.GetData()); DoWithErrMsgListUpdate(); startWithCfg(); } ErrorCodeEnum rc = Error_Succeed; if (Error_Succeed == (rc = GetFunction()->SubscribeLog(m_uuidVTMLoader, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "VtmLoader"))) LogManager::getInstance().logEntityStatus("订阅VtmLoader成功", LOG_LEVEL_INFO, 0, "none"); else LogManager::getInstance().logEntityStatus("订阅VtmLoader失败", LOG_LEVEL_ERROR, 2, "none", rc, ""); } }; boost::thread t(startFun); // 等待线程 3 秒,如果超时则 detach 线程 if (!t.timed_join(boost::chrono::seconds(3))) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Timed out, detaching thread."); t.detach(); } m_strArgs = strArgs; m_pTransactionContext = pTransactionContext; pTransactionContext->SendAnswer(Error_Succeed); #ifdef TEST_FUNCTION boost::thread(boost::bind(&CChromiumEntity::testLogError, this)).detach(); #endif // #ifdef TEST_FUNCTION } void CChromiumEntity::startupPageClean() { GUIConsole::GUIConsoleService_ClientBase* client = new GUIConsole::GUIConsoleService_ClientBase(this); ErrorCodeEnum error = client->Connect(); if (error == Error_Succeed) { { GUIConsole::GUIConsoleService_CloseLogSender_Req req; GUIConsole::GUIConsoleService_CloseLogSender_Ans ans; error = (*client)(EntityResource::getLink().upgradeLink())->CloseLogSender(req, ans, 1000); } { GUIConsole::GUIConsoleService_CloseEntityMonitor_Req req; GUIConsole::GUIConsoleService_CloseEntityMonitor_Ans ans; error = (*client)(EntityResource::getLink().upgradeLink())->CloseEntityMonitor(req, ans, 1000); } { GUIConsole::GUIConsoleService_ClosePerformanceSender_Req req; GUIConsole::GUIConsoleService_ClosePerformanceSender_Ans ans; error = (*client)(EntityResource::getLink().upgradeLink())->ClosePerformanceSender(req, ans, 1000); } client->GetFunction()->CloseSession(); } } bool CChromiumEntity::CheckIsCardStore() { return ConfigManager::getInstance().getSysInfo().strMachineType.IsEndWith("CardStore", true) || ConfigManager::getInstance().getSysInfo().strMachineType.IsEndWith("CardPrinter", true); } void CChromiumEntity::DoWithErrMsgListUpdate() { if (!isMsgTipExist()) { CAutoArray strErrorCodeArr; CAutoArray strDescriptionArr; CAutoArray strRemarkArr; auto ret = GetFunction()->GetPrivilegeFunction()->GetVTMErrMsgArr(strErrorCodeArr, strDescriptionArr, strRemarkArr); if (Error_Succeed == ret && strErrorCodeArr.GetCount() > 0) { InitUserCodeToMsgTip(strErrorCodeArr, strDescriptionArr, strRemarkArr); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("update msg tips success"); } } } void CChromiumEntity::DoWithTerminalStage_toA() { try { if (CModTools::get_mutable_instance().IsConfigWork())//url正常时才关闭 { if (ConfigManager::getInstance().m_runAd) openAdPage(); openMainPage(); CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::breakdown); std::this_thread::sleep_for(std::chrono::seconds(3)); LogWarn(Severity_Low, Error_Debug, LOG_SLV_CHROMIUM_URLOPEN, "正在启动业务界面"); CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::startup); startupPageClean(); //DbgEx("UnregistSysVarEvent TerminalStage %s", Error_Succeed == GetFunction()->UnregistSysVarEvent("TerminalStage") ? "success" : "fail"); } } catch (const std::exception& e) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("TerminalStage:A run exception, %s", e.what()); } } void CChromiumEntity::DoWithTerminalStage_toX() { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("TerminalStage X, do nothing."); } void CChromiumEntity::DoWithTerminalStage_toOther(std::string terminalStageVal) { try { if (!ConfigManager::getInstance().m_withBrowser) { if (ConfigManager::getInstance().m_existRootIni && ConfigManager::getInstance().m_installMode) return;//if root.ini exist and in install mode, do not close startup page CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::startup); startupPageClean(); ERR_PAGE_REASON reson = ERR_PAGE_REASON::breakdown; if (0 == CSimpleStringA("S").Compare(terminalStageVal.c_str(), true)) reson = ERR_PAGE_REASON::warnPrompt; else if(0 == CSimpleStringA("M").Compare(terminalStageVal.c_str(), true)) reson = ERR_PAGE_REASON::audioErr; auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(reson, std::tuple < std::string, std::string>(ConfigManager::getInstance().getSysInfo().strTerminalID.GetData(), generateTimeStr())); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("access failed, open err page %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::main); } } catch (const std::exception& e) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("TerminalStage:other run exception, %s", e.what()); } } void CChromiumEntity::DoWithSysVarEvent() { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); while (true) { if (ConfigManager::getInstance().m_eventArr.size() == 0) { boost::this_thread::sleep_for(boost::chrono::microseconds(100)); continue; } m_eventContorl.lock(); SYS_EVENT_PARAM curEvent = ConfigManager::getInstance().m_eventArr.front(); ConfigManager::getInstance().m_eventArr.pop_front(); m_eventContorl.unlock(); if ((strnicmp(curEvent.key.c_str(), "UIState", strlen("UIState")) == 0)) { if (strnicmp(curEvent.value.c_str(), "M", strlen("M")) == 0) { static bool firstEnter = true; if (firstEnter) { firstEnter = false; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("first Enter main page"); m_firstStartMain.unlock(); LogWarn(Severity_Low, Error_Debug, LOG_SLV_CHROMIUM_OPENSUCCESS, CSimpleStringA::Format("Chromium Enter main page success, %s", CModTools::get_mutable_instance().getFultureUrl().GetData())); } GetFunction()->UnregistSysVarEvent("UIState"); } } /** 该事件有变化才会触发错误页 [Gifur@2022324]*/ else if (0 == CSimpleStringA("TerminalStage").Compare(curEvent.key.c_str(), true)) { DoWithErrMsgListUpdate(); if (0 == CSimpleStringA("A").Compare(curEvent.value.c_str(), true)) DoWithTerminalStage_toA(); else if (0 == CSimpleStringA("X").Compare(curEvent.value.c_str(), true)) DoWithTerminalStage_toX(); else DoWithTerminalStage_toOther(curEvent.value); } else if (0 == CSimpleStringA("CardStoreInUse").Compare(curEvent.key.c_str(), true) && CheckIsCardStore()) { try { if (0 == CSimpleStringA("Y").Compare(curEvent.value.c_str(), true)) { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::CardStoreIsBusy, std::tuple (ConfigManager::getInstance().getSysInfo().strTerminalID.GetData(), generateTimeStr())); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CardStoreIsBusy, open page CardStoreIsBusy %s, %d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } else { CModTools::get_mutable_instance().StopChromiumBrowser_security(ERR_PAGE_REASON::CardStoreIsBusy, 2); } } catch (const std::exception& e) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CardStoreInUse run exception, %s", e.what()); } } } } #ifdef TEST_FUNCTION void CChromiumEntity::testLogError() { while(true) { LogError(SeverityLevelEnum::Severity_High, Error_Debug, LOG_WARN_CHROMIUM_VTMUSERMSG_ERR, "test log Error!"); boost::this_thread::sleep_for(boost::chrono::seconds(1)); } } #endif void CChromiumEntity::OnSysVarEvent(const char* pszKey, const char* pszValue, const char* pszOldValue, const char* pszEntityName) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnSysVarEvent %s, old->new:%s->%s", pszKey, pszOldValue, pszValue); SYS_EVENT_PARAM curEvent; curEvent.key = std::string(pszKey); curEvent.value = std::string(pszValue); curEvent.oldValue = std::string(pszOldValue); curEvent.entityName = std::string(pszEntityName); boost::unique_lock eventArrLock(m_eventContorl); ConfigManager::getInstance().m_eventArr.push_back(curEvent); } void CChromiumEntity::OnPreClose(EntityCloseCauseEnum eCloseCause, CSmartPointer pTransactionContext) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Chromium Run OnPreClose"); pTransactionContext->SendAnswer(Error_Succeed); exitClean(); } void CChromiumEntity::exitClean() { static bool isExit = false; if (!isExit) { isExit = true; CModTools::get_mutable_instance().killAllChromiumByThread(3); delete m_pWsServer; if (m_pTimerListener != NULL) { GetFunction()->KillTimer(CHROMIUM_TIMER_ID); delete m_pTimerListener; m_pTimerListener = NULL; } } } /** 查看启动顺序发现集中配置实体启动在本实体之前,无法调用集中配置的接口,随将实现搬到这里来 [Gifur@2021124]*/ void CChromiumEntity::FetchCustomMainUrl(CAutoArray& strArgs) { #if (defined _WIN32 || defined _WIN64) #else const int ArgsCount = strArgs.GetCount(); LOG_TRACE("strArgs.GetCount() = %d", ArgsCount); for (int i = 0; i < ArgsCount; ++i) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("strArgs[%d] = %s", i, strArgs[i].GetData()); } if (ArgsCount == 1) { ConfigManager::getInstance().m_strCustomMainUrl = strArgs[0].GetData(); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Get custom main url: %s", ConfigManager::getInstance().m_strCustomMainUrl.c_str()); if (!ConfigManager::getInstance().m_strCustomMainUrl.length() > 0) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_START, CSimpleStringA::Format("从模块入参获取自定义链接:%s", ConfigManager::getInstance().m_strCustomMainUrl.c_str())); } } else { CSmartPointer pConfig; GetFunction()->OpenConfig(Config_Cache, pConfig); int cnt(0), currentUsing(0); pConfig->ReadConfigValueInt("CustomWebUrl", "Count", cnt); pConfig->ReadConfigValueInt("CustomWebUrl", "Current", currentUsing); if (cnt > 0 && currentUsing > 0) { CSimpleStringA strAdUrl(true); CSimpleStringA strSection = CSimpleStringA::Format("CustomWebUrl%d", currentUsing); CSimpleString t_mainUrl = ConfigManager::getInstance().m_strCustomMainUrl.c_str(); pConfig->ReadConfigValue(strSection, "FultureUrl", t_mainUrl); pConfig->ReadConfigValue(strSection, "AdUrl", strAdUrl); if (!t_mainUrl.IsNullOrEmpty()) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_CONFIG, CSimpleStringA::Format("从本地维护桌面获取自定义链接:%s", t_mainUrl.GetData())); } } } #endif } void CChromiumEntity::OnLog(const CAutoArray& SubIDs, const CUUID nLogID, const LogTypeEnum eLogType, const SeverityLevelEnum eLevel, const DWORD dwSysError, const DWORD dwUserCode, const DWORD dwEntityInstanceID, const WORD wEntityDevelID, const CAutoArray& Param, const char* pszEntityName, const char* pszModuleName, const char* pszMessage, const linkContext& pLinkInfo) { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnLog %x from entity %s, msg : %s", dwUserCode, NULL == pszEntityName ? "" : pszEntityName, NULL == pszMessage ? "" : pszMessage); switch (dwUserCode) { case Event_VtmLoader_GetConfig_Suc: LogManager::getInstance().logEntityOnLog(NULL == pszEntityName ? "" : pszEntityName, dwUserCode, "Event_VtmLoader_GetConfig_Suc", 0, "none", Error_Succeed, "setHasInitCfg"); ConfigManager::getInstance().setHasInitCfg(true); case Event_VtmLoader_GetConfig_Fail: refreshLogLevel();//后置后需要刷新log level,因为chromium是先启动的实体 if (ConfigManager::getInstance().m_installMode)//Do not init Entity again in install mode break; //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("startWithCfg:open error or normal page"); if(dwUserCode == Event_VtmLoader_GetConfig_Fail) LogManager::getInstance().logEntityOnLog(NULL == pszEntityName ? "" : pszEntityName, dwUserCode, "Event_VtmLoader_GetConfig_Fail", 0, "openPage", Error_Succeed, "startWithCfg:open error or normal page"); boost::thread(boost::bind(&CChromiumEntity::startWithCfg, this)).detach();//open errPage or normal page break; case Event_VtmLoader_GetVTMERRMSG_Suc: LogManager::getInstance().logEntityOnLog(NULL == pszEntityName ? "" : pszEntityName, dwUserCode, "Event_VtmLoader_GetVTMERRMSG_Suc", 0, "none"); if (!GetFunction()->HasPrivilege()) { LogManager::getInstance().logEntityOnLog(NULL == pszEntityName ? "" : pszEntityName, dwUserCode, "Event_VtmLoader_GetVTMERRMSG_Suc", 2, "none", Error_NoPrivilege, "no privilege"); break; } { CAutoArray strErrorCodeArr; CAutoArray strDescriptionArr; CAutoArray strRemarkArr; auto ret = GetFunction()->GetPrivilegeFunction()->GetVTMErrMsgArr(strErrorCodeArr, strDescriptionArr, strRemarkArr); if (Error_Succeed == ret) InitUserCodeToMsgTip(strErrorCodeArr, strDescriptionArr, strRemarkArr); else { CSimpleString warnMsg = CSimpleStringA::Format("GetVTMErrMsgArr err:%d", ret); LogWarn(Severity_Low, Error_Debug, LOG_WARN_CHROMIUM_VTMUSERMSG_ERR, warnMsg.GetData()); LogManager::getInstance().logEntityOnLog(NULL == pszEntityName ? "" : pszEntityName, dwUserCode, "Event_VtmLoader_GetVTMERRMSG_Suc", 2, "none", Error_Bug, warnMsg.GetData()); } if (ConfigManager::getInstance().m_withSpecialTest) { CSimpleStringA strDescription, strVTMCode; GetFunction()->GetVTMErrMsg(0x2030020e, strDescription, strVTMCode); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetVTMErrMsg, %s:%s", strDescription.GetData(), strVTMCode.GetData()); } } break; default: break; } } void CChromiumEntity::OnBrowserCacheClean(const char* pszEntityName, DWORD dwMessageId, DWORD dwMessageSignature, ResourceWatcher::BrowserCacheClean& evt) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnOnBrowserCacheClean, needClean:%d", evt.needClean); ErrorCodeEnum error = Error_Succeed; if (!evt.needClean) return; CSimpleString tmpCacheDir; if (Error_Succeed != (error = GetFunction()->GetPath("Temp", tmpCacheDir)) || tmpCacheDir.GetLength() == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnBrowserCacheClean get cache path err, %d", error); return; } #if (defined _WIN32 || defined _WIN64) CModTools::get_mutable_instance().lockGuard(); auto tmpArr = find_files(tmpCacheDir.GetData(), "cefCache*", true); std::shared_ptr> tmpDirArr(new std::vector()); for each (auto it in tmpArr) tmpDirArr.get()->push_back(it); auto runCacheClean = [](std::shared_ptr> p) ->void { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::breakdown, true);//close all tab for each (auto it in *p.get()) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER, CSimpleStringA::Format("clear chromium browser cache %s %s", it.c_str(), RemoveDirRecursive(it.c_str()) ? "success" : "fail")); } }; boost::thread CacheCleanThread(runCacheClean, tmpDirArr); CacheCleanThread.timed_join(boost::posix_time::microseconds(10000)); CModTools::get_mutable_instance().unlockGuard(); /* if (ConfigManager::getInstance().m_runAd) { CModTools::get_mutable_instance().m_isAdOpen = false; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnBrowserCacheClean open add page"); openAdPage(); } */ #else //uos 由于无guard,需要重启整个chromium实体 CModTools::get_mutable_instance().killAllChromium(); auto tmpDirArr = find_files(tmpCacheDir.GetData(), "cefCache*", true); auto uosTmpDirArr = find_files(tmpCacheDir.GetData(), "UOSBrowser*", true); std::for_each(uosTmpDirArr.begin(), uosTmpDirArr.end(), [&](std::string tmp) { tmpDirArr.push_back(tmp); });//insert uosTmpDirArr into tmpDirArr for (auto it = tmpDirArr.begin(); it != tmpDirArr.end(); it++) LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER, CSimpleStringA::Format("clear chromium browser cache %s %s", it->c_str(), RemoveDirRecursive(it->c_str()) ? "success" : "fail")); if (m_pTimerListener != NULL) { GetFunction()->KillTimer(CHROMIUM_TIMER_ID); delete m_pTimerListener; m_pTimerListener = NULL; } if(!ConfigManager::getInstance().m_installMode) OnPreStart_openWeb();//重新调用open web #endif } void CChromiumEntity::generateCefclientTimer() { if (nullptr == m_pTimerListener) { m_pTimerListener = new TimerOutHelper(this, &CChromiumEntity::OnTaskTimerListener, NULL, false); GetFunction()->SetTimer(CHROMIUM_TIMER_ID, m_pTimerListener, 2000); //间隔执行时间 } } int CChromiumEntity::getBrowserStartTimes() { CAutoArray t_names; CAutoArray t_Idx; CAutoArray t_Infos; GetFunction()->GetAllEntityStartInfo(t_names, t_Idx, t_Infos); for (int i = 0; i < t_names.GetCount(); i++) { if (t_names[i] == GetEntityName()) return t_Infos[i].startTimes; } return -1; } void CChromiumEntity::checkUrlStartTime() { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); std::string startTimeStr = boost::posix_time::to_iso_extended_string(boost::posix_time::microsec_clock::local_time()); int pos = startTimeStr.find('T'); startTimeStr.replace(pos, 1, std::string(" ")); pos = startTimeStr.find('.'); startTimeStr.replace(pos, 1, std::string(":")); auto urlStartTime = boost::posix_time::microsec_clock::universal_time(); while (!m_firstStartMain.try_lock_for(boost::chrono::seconds(30))) DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("wait 30s, but slv did not start"); auto urlEndTime = boost::posix_time::microsec_clock::universal_time(); auto timeDuration = urlEndTime - urlStartTime; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("slv start at %s, used %d ms", startTimeStr.c_str(), timeDuration.total_milliseconds()); if (1 == getBrowserStartTimes()) { auto generateAlarmJson = [](CSimpleString entityName, CSimpleString startTime, int cost) ->CSimpleString { return CSimpleString::Format("[{\"name\":\"%s\",\"time\":\"%s\",\"cost\":%d}]", entityName.GetData(), startTime.GetData(), cost); }; LogWarn(Severity_Low, Error_Debug, LOG_TRACE_ENTITY_START_TIME, generateAlarmJson("slv", startTimeStr.c_str(), timeDuration.total_milliseconds()).GetData()); } m_firstStartMain.unlock(); }; void CChromiumEntity::DoBrowserCacheClearJob() { #if (defined _WIN32 || defined _WIN64) #else LOG_FUNCTION(); CSmartPointer spConfig; ErrorCodeEnum err = GetFunction()->OpenConfig(Config_Cache, spConfig); CSimpleStringA str(true); err = spConfig->ReadConfigValue("Browser", "CacheClear", str); if (str.Compare("true", true) == 0) { BOOL bSucc(FALSE); CSimpleStringA strCachePath; GetFunction()->GetPath("Temp", strCachePath); if (!strCachePath.IsNullOrEmpty()) { bSucc = TRUE; const char* cacheDirs[] = { "cefCache", "cefCache_Ad", "cefCache_breakdown","cefCache_ErrNotify", "cefCache_main" , "UOSBrowser_Ad", "UOSBrowser_main" , "UOSBrowserConfig_Ad", "UOSBrowserConfig_main" , "UOSBrowser2_Ad", "UOSBrowser2_main" , "UOSBrowserConfig2_Ad", "UOSBrowserConfig2_main" }; const int cacheDirsLength = (5 + 4 + 4); for (int i = 0; i < cacheDirsLength; ++i) { CSimpleStringA strcefCachePath(strCachePath); strcefCachePath += SPLIT_SLASH_STR; strcefCachePath += cacheDirs[i]; if (ExistsDirA(strcefCachePath)) { RemoveDirRecursiveA(strcefCachePath); LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_BROWSER_CACHE_CLEAER, CSimpleStringA::Format("clear chromium browser cache: %s", strcefCachePath.GetData())); } } } if (bSucc) { spConfig->WriteConfigValue("Browser", "CacheClear", NULL); } } #endif } void CChromiumEntity::OnTaskTimerListener(void* pData) { static int max_restartTime = 3; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnTaskTimerListener"); if (max_restartTime == 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("max_restartTime == 0, do not restart chromium"); GetFunction()->KillTimer(CHROMIUM_TIMER_ID); return; } static bool t_firstStartMain = true; if (t_firstStartMain) { t_firstStartMain = false; m_firstStartMain.lock(); boost::thread(boost::bind(&CChromiumEntity::checkUrlStartTime, this)).detach(); } auto rc = CModTools::get_mutable_instance().StartChromiumBrowser(); max_restartTime--; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("TaskTimerListen, startChromiumBrowser, rc:%d, pid:%d", rc.first, rc.second); if (0 == rc.first) GetFunction()->KillTimer(CHROMIUM_TIMER_ID); #if (defined _WIN32 || defined _WIN64) if (rc.first == Error_Succeed && rc.second != 0) { HANDLE defaultProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, rc.second); if (defaultProcess == nullptr) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnTaskTimerListener, openProcess failed"); return; } auto ret = assigntoJob(defaultProcess, rc.second); if (!ret.first) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnTaskTimerListener, assigntoJob failed"); else { auto monitorThread = [&](HANDLE job, HANDLE process) { //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); while (1) { if (WaitForSingleObject(process, 10) != WAIT_OBJECT_0) //process end DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("default cefclient.exe job:%d, process:%d checkOpen", job, process); else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("default cefclient.exe job:%d, process:%d check Closed, try to restart", job, process); TerminateJobObject(job, 0); max_restartTime--; generateCefclientTimer(); break; } boost::this_thread::sleep_for(boost::chrono::seconds(10)); } }; if (ret.second != nullptr && defaultProcess != nullptr) boost::thread(monitorThread, ret.second, defaultProcess).detach(); } } if (Error_Succeed != rc.first) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnTaskTimerListener will be called after %d secs, rest restart time %d", 15, max_restartTime); if (max_restartTime) GetFunction()->ResetTimer(CHROMIUM_TIMER_ID, 15000); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnTaskTimerListener rc = succeed"); GetFunction()->KillTimer(CHROMIUM_TIMER_ID); } #endif } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CChromiumEntity) SP_END_ENTITY_MAP() }