platform/shared/common/RhodesApp.cpp in rhodes-3.0.2 vs platform/shared/common/RhodesApp.cpp in rhodes-3.1.0.beta.1

- old
+ new

@@ -1,5 +1,31 @@ +/*------------------------------------------------------------------------ +* (The MIT License) +* +* Copyright (c) 2008-2011 Rhomobile, Inc. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +* +* http://rhomobile.com +*------------------------------------------------------------------------*/ + #include "RhodesApp.h" #include "common/RhoMutexLock.h" #include "common/IRhoClassFactory.h" #include "common/RhoConf.h" #include "common/RhoFilePath.h" @@ -76,10 +102,11 @@ static char const *toString(int type); private: callback_t m_expected; Vector<int> m_commands; + boolean m_bFirstServerStart; }; IMPLEMENT_LOGCLASS(CAppCallbacksQueue,"AppCallbacks"); char const *CAppCallbacksQueue::toString(int type) { @@ -99,14 +126,14 @@ return "UNKNOWN"; } } CAppCallbacksQueue::CAppCallbacksQueue() - :CThreadQueue(), m_expected(local_server_started) + :CThreadQueue(), m_expected(local_server_started), m_bFirstServerStart(true) { CThreadQueue::setLogCategory(getLogCategory()); - //setPollInterval(1); + setPollInterval(QUEUE_POLL_INTERVAL_INFINITE); start(epNormal); } CAppCallbacksQueue::~CAppCallbacksQueue() { @@ -120,10 +147,11 @@ void CAppCallbacksQueue::processCommand(IQueueCommand* pCmd) { Command *cmd = (Command *)pCmd; if (!cmd) return; + /* if (cmd->type < m_expected) { LOG(ERROR) + "received command " + toString(cmd->type) + " which is less than expected "+toString(m_expected)+" - ignore it"; return; @@ -135,11 +163,15 @@ return; } if ( m_expected == local_server_restart ) { - RHODESAPP().restartLocalServer(*this); + if ( cmd->type != local_server_started ) + RHODESAPP().restartLocalServer(*this); + else + LOG(INFO) + "Local server restarted before activate.Do not restart it again."; + m_expected = local_server_started; } if (cmd->type > m_expected) { @@ -164,10 +196,13 @@ std::sort(m_commands.begin(), m_commands.end()); } return; } + if ( cmd->type == app_deactivated ) + m_commands.clear(); + m_commands.insert(m_commands.begin(), cmd->type); for (Vector<int>::const_iterator it = m_commands.begin(), lim = m_commands.end(); it != lim; ++it) { int type = *it; LOG(INFO) + "process command: " + toString(type); @@ -180,11 +215,18 @@ m_expected = app_activated; #endif break; case local_server_started: - m_expected = ui_created; + if ( m_bFirstServerStart ) + { + m_expected = ui_created; + m_bFirstServerStart = false; + } + else + m_expected = app_activated; + rho_sys_report_app_started(); break; case ui_created: { String strUrl = RHODESAPP().getBaseUrl(); @@ -240,15 +282,16 @@ :CRhodesAppBase(strRootPath) { m_bExit = false; m_bDeactivationMode = false; m_bRestartServer = false; + m_bSendingLog = false; //m_activateCounter = 0; m_appCallbacksQueue = new CAppCallbacksQueue(); -#if defined( OS_WINCE ) || defined (OS_WINDOWS) +#if defined(OS_WINCE) || defined (OS_WINDOWS) //initializing winsock WSADATA WsaData; int result = WSAStartup(MAKEWORD(2,2),&WsaData); #endif @@ -359,10 +402,15 @@ private: virtual void run() { m_cb->run(*this); + } + + virtual void runObject() + { + common::CRhoThread::runObject(); delete this; } private: common::CAutoPtr<T> m_cb; @@ -797,13 +845,12 @@ } void CRhodesApp::initAppUrls() { CRhodesAppBase::initAppUrls(); - m_currentTabIndex = 0; - -#if defined( OS_WINCE ) + +#if defined( OS_WINCE ) || defined( __SYMBIAN32__ ) m_strHomeUrl = "http://localhost:"; #else m_strHomeUrl = "http://127.0.0.1:"; #endif m_strHomeUrl += getFreeListeningPort(); @@ -813,28 +860,78 @@ } void CRhodesApp::keepLastVisitedUrl(String strUrl) { //LOG(INFO) + "Current URL: " + strUrl; + int nIndex = rho_webview_active_tab(); + if (nIndex < 0) nIndex = 0; + int nToAdd = nIndex - m_currentUrls.size(); + for ( int i = 0; i <= nToAdd; i++ ) + { + m_currentUrls.addElement(""); + } - m_currentUrls[m_currentTabIndex] = canonicalizeRhoUrl(strUrl); + m_currentUrls[nIndex] = canonicalizeRhoUrl(strUrl); } +const String& CRhodesApp::getCurrentUrl(int index) +{ + if (index < 0) index = rho_webview_active_tab(); + if (index < 0) index = 0; + if ( index < m_currentUrls.size() ) + return m_currentUrls[index]; + + return m_EmptyString; +} + +const String& CRhodesApp::getAppBackUrl() +{ + int index = rho_webview_active_tab(); + if (index < 0) + index = 0; + if ( index < m_arAppBackUrl.size() ) + return m_arAppBackUrl[index]; + + return m_EmptyString; +} + void CRhodesApp::setAppBackUrl(const String& url) { + int nIndex = rho_webview_active_tab(); + if (nIndex < 0) + nIndex = 0; + int nToAdd = nIndex - m_arAppBackUrl.size(); + for ( int i = 0; i <= nToAdd; i++ ) + { + m_arAppBackUrl.addElement(""); + m_arAppBackUrlOrig.addElement(""); + } + if ( url.length() > 0 ) { - m_strAppBackUrlOrig = url; - m_strAppBackUrl = canonicalizeRhoUrl(url); + m_arAppBackUrlOrig[nIndex] = url; + m_arAppBackUrl[nIndex] = canonicalizeRhoUrl(url); } else { - m_strAppBackUrlOrig = ""; - m_strAppBackUrl = ""; + m_arAppBackUrlOrig[nIndex] = ""; + m_arAppBackUrl[nIndex] = ""; } } +void CRhodesApp::navigateBack() +{ + int nIndex = rho_webview_active_tab(); + + if ( nIndex < m_arAppBackUrlOrig.size() && m_arAppBackUrlOrig[nIndex].length() > 0 ) + loadUrl(m_arAppBackUrlOrig[nIndex]); + else if ( strcasecmp(getCurrentUrl(nIndex).c_str(),getStartUrl().c_str()) != 0 ) + { + rho_webview_navigate_back(); + } +} + String CRhodesApp::getAppName() { String strAppName; #ifdef OS_WINCE String path = rho_native_rhopath(); @@ -904,15 +1001,10 @@ { m_strOptionsUrl = canonicalizeRhoUrl( RHOCONF().getString("options_path") ); return m_strOptionsUrl; } -const String& CRhodesApp::getCurrentUrl(int /*index*/) -{ - return m_currentUrls[m_currentTabIndex]; -} - const String& CRhodesApp::getRhobundleReloadUrl() { m_strRhobundleReloadUrl = RHOCONF().getString("rhobundle_zip_url"); return m_strRhobundleReloadUrl; } @@ -920,61 +1012,66 @@ void CRhodesApp::navigateToUrl( const String& strUrl) { rho_webview_navigate(strUrl.c_str(), -1); } -void CRhodesApp::navigateBack() +class CRhoSendLogCall { - //rho::String strAppUrl = getAppBackUrl(); + String m_strCallback; +public: + CRhoSendLogCall(const String& strCallback): m_strCallback(strCallback){} - if ( m_strAppBackUrlOrig.length() > 0 ) - loadUrl(m_strAppBackUrlOrig); - else if ( strcasecmp(getCurrentUrl().c_str(),getStartUrl().c_str()) != 0 ) - { -/* Now JQTouch is fixed for back issue - we do not need make back by this hack -#ifdef OS_MACOSX - if (RHOCONF().getBool("jqtouch_mode")) - { - rho_webview_execute_js("window.Rho.jqt.goBack()", 0); - return; - } -#endif -*/ - rho_webview_navigate_back(); - } -} + void run(common::CRhoThread &) + { + String strDevicePin = rho::sync::CClientRegister::getInstance() ? rho::sync::CClientRegister::getInstance()->getDevicePin() : ""; + String strClientID = rho::sync::CSyncThread::getSyncEngine().readClientID(); + + String strLogUrl = RHOCONF().getPath("logserver"); + if ( strLogUrl.length() == 0 ) + strLogUrl = RHOCONF().getPath("syncserver"); + + String strQuery = strLogUrl + "client_log?" + + "client_id=" + strClientID + "&device_pin=" + strDevicePin + "&log_name=" + RHOCONF().getString("logname"); + + net::CMultipartItem oItem; + oItem.m_strFilePath = LOGCONF().getLogFilePath(); + oItem.m_strContentType = "application/octet-stream"; + + boolean bOldSaveToFile = LOGCONF().isLogToFile(); + LOGCONF().setLogToFile(false); + NetRequest oNetRequest; + oNetRequest.setSslVerifyPeer(false); + + NetResponse resp = getNetRequest(&oNetRequest).pushMultipartData( strQuery, oItem, &(rho::sync::CSyncThread::getSyncEngine()), null ); + LOGCONF().setLogToFile(bOldSaveToFile); + + boolean isOK = true; + + if ( !resp.isOK() ) + { + LOG(ERROR) + "send_log failed : network error - " + resp.getRespCode() + "; Body - " + resp.getCharData(); + isOK = false; + } -boolean CRhodesApp::sendLog() -{ - String strDevicePin = rho::sync::CClientRegister::getInstance() ? rho::sync::CClientRegister::getInstance()->getDevicePin() : ""; - String strClientID = rho::sync::CSyncThread::getSyncEngine().readClientID(); + if (m_strCallback.length() > 0) + { + String body = isOK ? "rho_callback=1&status=ok" : "rho_callback=1&status=error"; - String strLogUrl = RHOCONF().getPath("logserver"); - if ( strLogUrl.length() == 0 ) - strLogUrl = RHOCONF().getPath("syncserver"); + rho_net_request_with_data(rho_http_normalizeurl(m_strCallback.c_str()), body.c_str()); + } - String strQuery = strLogUrl + "client_log?" + - "client_id=" + strClientID + "&device_pin=" + strDevicePin + "&log_name=" + RHOCONF().getString("logname"); - - net::CMultipartItem oItem; - oItem.m_strFilePath = LOGCONF().getLogFilePath(); - oItem.m_strContentType = "application/octet-stream"; - - boolean bOldSaveToFile = LOGCONF().isLogToFile(); - LOGCONF().setLogToFile(false); - NetRequest oNetRequest; - oNetRequest.setSslVerifyPeer(false); - - NetResponse resp = getNetRequest(&oNetRequest).pushMultipartData( strQuery, oItem, &(rho::sync::CSyncThread::getSyncEngine()), null ); - LOGCONF().setLogToFile(bOldSaveToFile); - - if ( !resp.isOK() ) - { - LOG(ERROR) + "send_log failed : network error - " + resp.getRespCode() + "; Body - " + resp.getCharData(); - return false; + RHODESAPP().setSendingLog(false); } +}; +boolean CRhodesApp::sendLog( const String& strCallbackUrl) +{ + if ( m_bSendingLog ) + return true; + + m_bSendingLog = true; + rho_rhodesapp_call_in_thread( new CRhoSendLogCall(strCallbackUrl) ); return true; } String CRhodesApp::addCallbackObject(ICallbackObject* pCallbackObject, String strName) { @@ -1382,13 +1479,17 @@ int rho_rhodesapp_isrubycompiler() { return 0; } -int rho_conf_send_log() +int rho_conf_send_log(const char* callback_url) { - return RHODESAPP().sendLog(); + rho::String s_callback_url = ""; + if (callback_url != NULL) { + s_callback_url = callback_url; + } + return RHODESAPP().sendLog(s_callback_url); } void rho_net_request(const char *url) { getNetRequest().pullData(url, null); @@ -1437,18 +1538,19 @@ //It is used in SyncClient. } int rho_rhodesapp_canstartapp(const char* szCmdLine, const char* szSeparators) { + String strCmdLineSecToken; + String security_key = "security_token="; + String strCmdLine = szCmdLine ? szCmdLine : ""; + CRhodesApp::setStartParameters(szCmdLine); + RAWLOGC_INFO1("RhodesApp", "New start params: %s", strCmdLine.c_str()); const char* szAppSecToken = get_app_build_config_item("security_token"); if ( !szAppSecToken || !*szAppSecToken) return 1; - - String strCmdLineSecToken; - String security_key = "security_token="; - String strCmdLine = szCmdLine ? szCmdLine : ""; int skpos = strCmdLine.find(security_key); if ((String::size_type)skpos != String::npos) { String tmp = strCmdLine.substr(skpos+security_key.length(), strCmdLine.length() - security_key.length() - skpos);