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);