#include "stdafx.h" #if (defined _WIN32 || defined _WIN64) #include #include #include #define SPLIT_SLASH_STR "\\" #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 "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_iTcpBridgePort(4504), m_pTimerListener(NULL), m_strCustomMainUrl(true) , m_runAd(false), m_runMain(false), m_runExtend(false), m_runLogin(false), m_withBrowser(false), m_withMin(false), m_withClose(false) , m_withDebugMode(false), m_withMagic(false), m_withNoFileLog(false), m_installMode(false), m_withMedia(false), m_withSpecialTest(false), m_withConsole(false), m_withLinkLog(false), m_withUnsafeAd(false) { 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 (m_commonPageArr.find(strTitle) == m_commonPageArr.end()) { std::vector tmp; 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); 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 (m_commonPageArr.find(strName) != m_commonPageArr.end()) { auto arr = 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(); m_commonPageArr[strName] = arr; } std::this_thread::sleep_for(std::chrono::seconds(1)); #endif // RVC_OS_WIN ctx->Answer(ErrorCodeEnum::Error_Succeed); }; 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) { LOG_FUNCTION(); #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) { m_strCustomMainUrl = strArgs[0]; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Get custom main ulr: %s", m_strCustomMainUrl.GetData()); } else if (ArgsCount == 2) { m_strCustomMainUrl = strArgs[0]; m_strCustomAdUrl = strArgs[1]; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Get custom main url: %s, ad url: %s", m_strCustomMainUrl.GetData(), m_strCustomAdUrl.GetData()); } #endif GetFunction()->GetSystemStaticInfo(m_sysInfo); if (!IsConfigMode()) { CSmartPointer spConfig; if (Error_Succeed == GetFunction()->OpenConfig(Config_CenterSetting, spConfig))//特别坑,这个OpenConfig返回一直都是success { auto webMaskKey = CSimpleString::Format("WebMask_%s", m_sysInfo.strMachineType.GetData()); CSimpleString webMaskStr; 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 m_runAd = true; else if (!trimStr.Compare("main", true))//will open main browser m_runMain = true; else if (!trimStr.Compare("extend", true))//will open extend browser m_runExtend = true; else if (!trimStr.Compare("login", true))//will open login(User Desktop) browser m_runLogin = true; else if (!trimStr.Compare("with_browser", true))//will not open any browser m_withBrowser = true; else if (!trimStr.Compare("with_min", true))//the errPage contains min button m_withMin = true; else if (!trimStr.Compare("with_close", true))//the errPage contains close button m_withClose = true; else if (!trimStr.Compare("with_debugmode", true))//the browser will open remote control function m_withDebugMode = true; else if (!trimStr.Compare("with_magic", true))//the browser will open special queue for log sender. m_withMagic = true; else if (!trimStr.Compare("with_media", true))//the browser will support media play and RTC function m_withMedia = true; else if (!trimStr.Compare("with_unsafe_ad", true)) m_withUnsafeAd = g_unsafeAd = true; else if (!trimStr.Compare("with_specialTest", true))//chromium will run specical test m_withSpecialTest = true; else if (!trimStr.Compare("with_LinkLog", true))//control do_sendJson to print more logs(request) m_withLinkLog = true; else if (!trimStr.Compare("with_nofilelog", true))//DbgEx do not print logs to local storage, but DbgEx() is discard. m_withNoFileLog = true; else if (!trimStr.Compare("with_console", true))//control browser will print console logs g_withConsole = m_withConsole = true; } #if (defined _WIN32 || defined _WIN64) if (m_withDebugMode) CModTools::get_mutable_instance().setWithDebugMode(m_withDebugMode); #else //对于UOS来说,没有最小化和关闭按钮 m_withMin = false; m_withClose = false; #endif 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); if (m_withMin) CModTools::get_mutable_instance().setWithMin(m_withMin); if (m_withClose) CModTools::get_mutable_instance().setWithClose(m_withClose); g_logToFile = !m_withNoFileLog; g_withMedia = m_withMedia; g_withLinkLog = 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()); } if (!m_runAd && !m_runMain && !m_runExtend && !m_withBrowser) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("can not open centerSetting, maybe fault"); } #ifdef RVC_OS_WIN if (m_withMagic) { std::string magicStr = CModTools::get_mutable_instance().getMagicStr(); boost::thread(boost::bind(SaveCefclientLog, magicStr)).detach(); } #endif } if (m_withSpecialTest) { CSimpleString strPath; GetFunction()->GetPath("Downloads", strPath); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Downloads path %s, ", strPath.GetData()); } } bool CChromiumEntity::OnPreStart_socketStart(CAutoArray& strArgs, CSmartPointer& pTransactionContext) { ErrorCodeEnum Error; if (Error_Succeed != (Error = GetFunction()->StartTcpBridgeServer(m_iTcpBridgePort))) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("start tcp bridge server failed!"); pTransactionContext->SendAnswer(Error); return false; } // load all struct define xml & start websocket server CSimpleStringA strStructPath; GetFunction()->GetPath("Base", strStructPath); strStructPath.Append(CSimpleStringA(SPLIT_SLASH_STR) + "res" + SPLIT_SLASH_STR + "StructConfig" + SPLIT_SLASH_STR); 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(); return true; } bool CChromiumEntity::OnPreStart_register(CAutoArray& strArgs, CSmartPointer& pTransactionContext) { ErrorCodeEnum Error; #if defined(RVC_OS_LINUX) Error = GetFunction()->SubscribeLog(m_uuidAllFault, this, Log_Notify, Severity_High, Error_IgnoreAll, -2, NULL, false); if (Error_Succeed == Error) { this->GetFunction()->GetPrivilegeFunction()->RefreshFrameworkState(FrameworkState_NotDisturb); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("subscribe log for notify failed! %s", SpStrError(Error)); } #endif //RVC_OS_LINUX if (!m_withBrowser) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("subscribe AccessAuthorization %s, %d", Error_Succeed == (Error = GetFunction()->SubscribeLog(m_uuidAccessAuth, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "AccessAuthorization")) ? "success" : "failed", Error); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("subscribe ResourceWatcher %s, %d", Error_Succeed == (Error = GetFunction()->SubscribeBroadcast("ResourceWatcher", NULL, this, m_uuidResourceWatch)) ? "success" : "failed", Error); if (Error_Succeed != GetFunction()->RegistSysVarEvent("UIState", this)) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("RegistSysVarEvent UIState failed!"); if (Error_Succeed != GetFunction()->RegistSysVarEvent("TerminalStage", this)) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("RegistSysVarEvent TerminalStage failed!"); if (Error_Succeed != GetFunction()->RegistSysVarEvent("CardStoreInUse", this)) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("RegistSysVarEvent CardStoreInUse failed!"); } return true; } bool CChromiumEntity::OnPreStart_openWeb() { if (m_runExtend) openExtendPage(); if (!m_runMain)//不启动页面 return true; do { CSimpleStringA t_terminalState; ErrorCodeEnum rc = ErrorCodeEnum::Error_Succeed; if ((rc = GetFunction()->GetSysVar("TerminalStage", t_terminalState)) != ErrorCodeEnum::Error_Succeed) { 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 (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 (m_sysInfo.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 { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::breakdown, std::tuple (m_sysInfo.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); } } else { if (m_runAd) openAdPage(); openMainPage(); #if (defined _WIN32 || defined _WIN64) if (m_withDebugMode) getNetworkInfo(L"127.0.0.1:9222", L"", &DbgByCefControl); #endif } } while (false); return true; } void CChromiumEntity::openMainPage() { #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); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page Ad %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } void CChromiumEntity::openExtendPage() { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::extend); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page extend %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } void CChromiumEntity::openInstallPage() { /* LogWarn(Severity_Middle, Error_NotSupport, LOG_WARN_CHROMIUM_INSTALL_NOTSURPORT, CSimpleStringA::Format("Not surport install mode").GetData()); return; */ auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::Install); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page install %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } void CChromiumEntity::openStartupPage() { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::startup); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page startup %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } void CChromiumEntity::openPerformanceMonitorPage() { auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser(ERR_PAGE_REASON::performance_monitor); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("open page performance_monitor %s, pid:%d", Error_Succeed == openRet.first ? "success" : "fail", openRet.second); } 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()) { if (!m_strCustomMainUrl.IsNullOrEmpty()) openMainPage(); if (!m_strCustomAdUrl.IsNullOrEmpty()) openAdPage(); return; } #endif if (!OnPreStart_openWeb()) { return; } } else { openInstallPage(); LogEvent(Severity_High, LOG_EVT_CHROMIUM_OPEN_INSTALLPAGE, CSimpleStringA::Format("open install page")); } } void CChromiumEntity::OnPreStart(CAutoArray strArgs, CSmartPointer pTransactionContext) { #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 (!logProducer) logProducer = 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; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("OnPreStart - OnPreStart_socketStart end"); //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 { openStartupPage();//open startup page in install mode m_installMode = true; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("subscribe VtmLoader %s", (Error_Succeed == GetFunction()->SubscribeLog(m_uuidVTMLoader, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "VtmLoader")) ? "success" : "failed"); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("startWithCfg:open install page"); //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 defined(RVC_OS_LINUX) for (auto it : srcPids) { CSimpleStringA cmd = CSimpleStringA::Format("sudo kill -9 %d", it); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("CloseCommonPage %s", cmd.GetData()); system(cmd.GetData()); } #else CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::startup); #endif 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); if (m_withSpecialTest) { CSimpleStringA strDescription, strVTMCode; GetFunction()->GetVTMErrMsg(123456, strDescription, strVTMCode); } //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 { openStartupPage();//open startup page in normal mode DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("subscribe VtmLoader %s", (Error_Succeed == GetFunction()->SubscribeLog(m_uuidVTMLoader, this, Log_Event, Severity_None, Error_IgnoreAll, -1, "VtmLoader")) ? "success" : "failed"); } }; 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 } bool CChromiumEntity::CheckIsCardStore() { return m_sysInfo.strMachineType.IsEndWith("CardStore", true) || m_sysInfo.strMachineType.IsEndWith("CardPrinter", true); } void CChromiumEntity::DoWithSysVarEvent() { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create thread:%s", __FUNCTION__); while (true) { if (m_eventArr.size() == 0) { boost::this_thread::sleep_for(boost::chrono::microseconds(100)); continue; } m_eventContorl.lock(); SYS_EVENT_PARAM curEvent = m_eventArr.front(); 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)) { if (0 == CSimpleStringA("A").Compare(curEvent.value.c_str(), true)) { try { if (CModTools::get_mutable_instance().IsConfigWork())//url正常时才关闭 { #if defined(RVC_OS_LINUX) auto srcPids = getUosBrowserPIDs(CModTools::get_mutable_instance().getUosBrowser()); #endif // RVC_OS_UOS if (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, "正在启动业务界面"); #if defined(RVC_OS_LINUX) for (auto it : srcPids) { CSimpleStringA cmd = CSimpleStringA::Format("sudo kill -9 %d", it); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("CloseCommonPage %s", cmd.GetData()); system(cmd.GetData()); } #else CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::startup); #endif //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()); } } else if (0 == CSimpleStringA("X").Compare(curEvent.value.c_str(), true)) DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("TerminalStage X, do nothing."); else { try { if (!m_withBrowser) { #if defined(RVC_OS_LINUX) auto srcPids = getUosBrowserPIDs(CModTools::get_mutable_instance().getUosBrowser()); #endif // RVC_OS_UOS #if defined(RVC_OS_LINUX) for (auto it : srcPids) { CSimpleStringA cmd = CSimpleStringA::Format("sudo kill -9 %d", it); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("CloseCommonPage %s", cmd.GetData()); system(cmd.GetData()); } #else CModTools::get_mutable_instance().StopChromiumBrowser(ERR_PAGE_REASON::startup); #endif auto openRet = CModTools::get_mutable_instance().StartChromiumBrowser( 0 == CSimpleStringA("S").Compare(curEvent.value.c_str(), true) ? ERR_PAGE_REASON::warnPrompt : ERR_PAGE_REASON::breakdown, std::tuple < std::string, std::string>(m_sysInfo.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()); } } } 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 (m_sysInfo.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); m_eventArr.push_back(curEvent); } void CChromiumEntity::OnPreClose(EntityCloseCauseEnum eCloseCause, CSmartPointer pTransactionContext) { exitClean(); pTransactionContext->SendAnswer(Error_Succeed); } 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; } GetFunction()->UnsubscribeBroadcast("IEBrowser"); } } /** 查看启动顺序发现集中配置实体启动在本实体之前,无法调用集中配置的接口,随将实现搬到这里来 [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) { m_strCustomMainUrl = strArgs[0]; DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Get custom main url: %s", m_strCustomMainUrl.GetData()); if (!m_strCustomMainUrl.IsNullOrEmpty()) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_START, CSimpleStringA::Format("从模块入参获取自定义链接:%s", m_strCustomMainUrl.GetData())); } } 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); pConfig->ReadConfigValue(strSection, "FultureUrl", m_strCustomMainUrl); pConfig->ReadConfigValue(strSection, "AdUrl", strAdUrl); if (!m_strCustomMainUrl.IsNullOrEmpty()) { LogWarn(Severity_Low, Error_Debug, LOG_EVT_CHROMIUM_DETECT_CUSTOM_FULTURE_URL_FROM_CONFIG, CSimpleStringA::Format("从本地维护桌面获取自定义链接:%s", m_strCustomMainUrl.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: g_hasInitCfg = true; case Event_VtmLoader_GetConfig_Fail: refreshLogLevel();//后置后需要刷新log level,因为chromium是先启动的实体 if (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"); startWithCfg();//open errPage or normal page break; case Event_VtmLoader_GetVTMERRMSG_Suc: /* CSimpleString translatePath; GetFunction()->GetPath("Cfg", translatePath); translatePath.Append(CSimpleStringA(SPLIT_SLASH_STR) + "UserCodeToMsgTip.ini"); InitTranslateFile(translatePath.GetData()); */ if (!GetFunction()->HasPrivilege()) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("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 LogWarn(Severity_Low, Error_Debug, LOG_WARN_CHROMIUM_VTMUSERMSG_ERR, CSimpleStringA::Format("GetVTMErrMsgArr err:%d", ret)); if (m_withSpecialTest) { CSimpleStringA strDescription, strVTMCode; GetFunction()->GetVTMErrMsg(123456, strDescription, strVTMCode); } } 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 (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(!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() }