platform/shared/common/RhodesApp.cpp in rhodes-1.4.2 vs platform/shared/common/RhodesApp.cpp in rhodes-1.5.0

- old
+ new

@@ -1,13 +1,14 @@ #include "RhodesApp.h" #include "common/RhoMutexLock.h" #include "common/IRhoClassFactory.h" #include "common/RhoConf.h" +#include "common/RhoFilePath.h" #include "net/INetRequest.h" #include "net/HttpServer.h" #include "ruby/ext/rho/rhoruby.h" -#include <math.h> +//#include <math.h> #include "sync/ClientRegister.h" #include "sync/SyncThread.h" #include "net/AsyncHttp.h" #ifdef OS_WINCE @@ -22,13 +23,10 @@ extern "C" { void rho_sync_create(); void rho_sync_destroy(); void rho_sync_doSyncAllSources(int show_status_popup); -double geo_latitude(); -double geo_longitude(); -int geo_known_position(); void rho_map_location(char* query); void rho_appmanager_load( void* httpContext, const char* szQuery); void webview_navigate(char* url, int index); } @@ -38,11 +36,11 @@ IMPLEMENT_LOGCLASS(CRhodesApp,"RhodesApp"); CRhodesApp* CRhodesApp::m_pInstance = 0; /*static*/ CRhodesApp* CRhodesApp::Create(const String& strRootPath) { - if ( m_pInstance ) + if ( m_pInstance != null) return m_pInstance; m_pInstance = new CRhodesApp(strRootPath); return m_pInstance; } @@ -64,20 +62,23 @@ m_shttpdCtx = 0; #endif m_ptrFactory = createClassFactory(); m_NetRequest = m_ptrFactory->createNetRequest(); + m_oGeoLocation.init(m_ptrFactory); #if defined( OS_WINCE ) || defined (OS_WINDOWS) //initializing winsock WSADATA WsaData; int result = WSAStartup(MAKEWORD(2,2),&WsaData); #endif - //rho_logconf_Init(m_strRhoRootPath.c_str()); + //rho_logconf_Init(m_strRhoRootPath.c_str()); initAppUrls(); //start(epNormal); + + getSplashScreen().init(); } void CRhodesApp::startApp() { start(epNormal); @@ -91,17 +92,18 @@ LOG(INFO) + "Starting sync engine..."; rho_sync_create(); LOG(INFO) + "RhoRubyInitApp..."; RhoRubyInitApp(); - LOG(INFO) + "Call app active callback"; - callAppActiveCallback(); + LOG(INFO) + "activate app"; rho_ruby_activateApp(); + getSplashScreen().hide(); + LOG(INFO) + "navigate to first start url"; - navigateToUrl(getFirstStartUrl());//canonicalizeRhoUrl("/system/geolocation")); + navigateToUrl(getFirstStartUrl()); #if !defined(RHO_HTTPD_COMMON_IMPL) while(!m_bExit) { shttpd_poll( m_shttpdCtx, 100000 ); @@ -158,33 +160,52 @@ } class CRhoCallbackCall : public common::CRhoThread { common::CAutoPtr<common::IRhoClassFactory> m_ptrFactory; - String m_strCallback; + String m_strCallback, m_strBody; public: - CRhoCallbackCall(const String& strCallback, common::IRhoClassFactory* factory) : CRhoThread(factory), m_ptrFactory(factory), m_strCallback(strCallback) + CRhoCallbackCall(const String& strCallback, const String& strBody, common::IRhoClassFactory* factory) : CRhoThread(factory), + m_ptrFactory(factory), m_strCallback(strCallback), m_strBody(strBody) { start(epNormal); } private: virtual void run() { common::CAutoPtr<net::INetRequest> pNetRequest = m_ptrFactory->createNetRequest(); - common::CAutoPtr<net::INetResponse> presp = pNetRequest->pushData( m_strCallback, "", null ); + common::CAutoPtr<net::INetResponse> presp = pNetRequest->pushData( m_strCallback, m_strBody, null ); delete this; } }; -void CRhodesApp::callAppActiveCallback() +void CRhodesApp::runCallbackInThread(const String& strCallback, const String& strBody) { - /*String strCallback = RHOCONF().getString("app_did_become_active_callback"); - if ( strCallback.length() == 0 ) - return; + new CRhoCallbackCall(strCallback, strBody, createClassFactory() ); +} - new CRhoCallbackCall( canonicalizeRhoUrl(strCallback), m_ptrFactory );*/ +static void callback_activateapp(void *arg, String const &strQuery) +{ + rho_ruby_activateApp(); + String strMsg; + rho_http_sendresponse(arg, strMsg.c_str()); } +void CRhodesApp::callAppActiveCallback(boolean bActive) +{ + m_httpServer->pause(!bActive); + if (bActive) + { + String strUrl = m_strHomeUrl + "/system/activateapp"; + NetResponse(resp,getNet().pullData( strUrl, null )); + if ( !resp.isOK() ) + LOG(ERROR) + "activate app failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData(); + + LOG(INFO) + "navigate to first start url"; + navigateToUrl(getFirstStartUrl()); + } +} + void CRhodesApp::callCameraCallback(String strCallbackUrl, const String& strImagePath, const String& strError, boolean bCancel ) { strCallbackUrl = canonicalizeRhoUrl(strCallbackUrl); String strBody; @@ -218,35 +239,10 @@ strBody += "&rho_callback=1"; NetRequest( getNet().pushData( strCallbackUrl, strBody, null ) ); } -static void callback_geolocation(void *arg -#if defined(RHO_HTTPD_COMMON_IMPL) - , String const &/*query*/ -#endif - ) -{ - if (!geo_known_position()) - { - rho_http_sendresponse(arg, "Reading;Reading;Reading"); - return; - } - - double latitude = geo_latitude(); - double longitude = geo_longitude(); - - char location[256]; - sprintf(location,"%.4f\xc2\xb0 %s, %.4f\xc2\xb0 %s;%f;%f", - fabs(latitude),latitude < 0 ? "South" : "North", - fabs(longitude),longitude < 0 ? "West" : "East", - latitude,longitude); - - LOGC(INFO,CRhodesApp::getLogCategory())+ "Location: " + location; - rho_http_sendresponse(arg, location); -} - static void callback_syncdb(void *arg #if defined(RHO_HTTPD_COMMON_IMPL) , String const &/*query*/ #endif ) @@ -262,11 +258,11 @@ ) { #if !defined(RHO_HTTPD_COMMON_IMPL) String strQuery = shttpd_get_env((shttpd_arg *)arg,"QUERY_STRING"); #endif - size_t nUrl = strQuery.find_first_of("url="); + size_t nUrl = strQuery.find("url="); String strUrl; if ( nUrl != String::npos ) strUrl = strQuery.substr(nUrl+4); if ( strUrl.length() == 0 ) @@ -307,10 +303,48 @@ String query = shttpd_get_env((shttpd_arg *)arg,"QUERY_STRING"); #endif rho_appmanager_load( arg, query.c_str() ); } +static void callback_getrhomessage(void *arg, String const &strQuery) +{ + String strMsg; + size_t nErrorPos = strQuery.find("error="); + if ( nErrorPos != String::npos ) + { + String strError = strQuery.substr(nErrorPos+6); + int nError = atoi(strError.c_str()); + + strMsg = rho_ruby_internal_getErrorText(nError); + } + + rho_http_sendresponse(arg, strMsg.c_str()); +} + +const String& CRhodesApp::getRhoMessage(int nError, const char* szName) +{ + String strUrl = m_strHomeUrl + "/system/getrhomessage?"; + if ( nError ) + strUrl += "error=" + convertToStringA(nError); + else if ( szName && *szName ) + { + strUrl = "msgid="; + strUrl += szName; + } + + NetResponse(resp,getNet().pullData( strUrl, null )); + if ( !resp.isOK() ) + { + LOG(ERROR) + "getRhoMessage failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData(); + m_strRhoMessage = ""; + } + else + m_strRhoMessage = resp.getCharData(); + + return m_strRhoMessage; +} + void CRhodesApp::initHttpServer() { String strAppRootPath = getRhoRootPath() + "apps"; #if !defined(RHO_HTTPD_COMMON_IMPL) @@ -328,16 +362,18 @@ shttpd_register_uri(m_shttpdCtx, "/system/shared", callback_shared, this); shttpd_register_uri(m_shttpdCtx, "/AppManager/loader/load", callback_AppManager_load, this); #else m_httpServer = new net::CHttpServer(atoi(getFreeListeningPort()), strAppRootPath); - m_httpServer->register_uri("/system/geolocation", callback_geolocation); + m_httpServer->register_uri("/system/geolocation", rubyext::CGeoLocation::callback_geolocation); m_httpServer->register_uri("/system/syncdb", callback_syncdb); m_httpServer->register_uri("/system/redirect_to", callback_redirect_to); m_httpServer->register_uri("/system/map", callback_map); m_httpServer->register_uri("/system/shared", callback_shared); m_httpServer->register_uri("/AppManager/loader/load", callback_AppManager_load); + m_httpServer->register_uri("/system/getrhomessage", callback_getrhomessage); + m_httpServer->register_uri("/system/activateapp", callback_activateapp); #endif } const char* CRhodesApp::getFreeListeningPort() { @@ -412,20 +448,21 @@ LOG(INFO) + "Free listening port: " + m_strListeningPorts; return m_strListeningPorts.c_str(); } - + void CRhodesApp::initAppUrls() { m_currentTabIndex = 0; m_strHomeUrl = "http://localhost:"; m_strHomeUrl += getFreeListeningPort(); m_strBlobsDirPath = getRhoRootPath() + "apps/public/db-files"; - m_strLoadingPagePath = "file://" + getRhoRootPath() + "apps/loading.html"; + m_strLoadingPagePath = "file://" + getRhoRootPath() + "apps/app/loading.html"; + m_strLoadingPngPath = getRhoRootPath() + "apps/app/loading.png"; } void CRhodesApp::keepLastVisitedUrl(String strUrl) { LOG(INFO) + "Current URL: " + strUrl; @@ -450,15 +487,10 @@ { m_strStartUrl = canonicalizeRhoUrl( RHOCONF().getString("start_path") ); return m_strStartUrl; } -const char* rho_rhodesapp_gethomeurl() -{ - return RHODESAPP().getHomeUrl().c_str(); -} - const String& CRhodesApp::getOptionsUrl() { m_strOptionsUrl = canonicalizeRhoUrl( RHOCONF().getString("options_path") ); return m_strOptionsUrl; } @@ -500,17 +532,11 @@ if ( strncmp("http://", strUrl.c_str(), 7 ) == 0 || strncmp("mailto:", strUrl.c_str(), 7) == 0 || strncmp("tel:", strUrl.c_str(), 4) == 0) return strUrl; - String strRes = m_strHomeUrl; - if ( strUrl.at(0) != '/' && strUrl.at(0) != '\\' ) - strRes += '/'; - - strRes += strUrl; - - return strRes; + return CFilePath::join(m_strHomeUrl,strUrl); } void CRhodesApp::addViewMenuItem( const String& strLabel, const String& strLink ) { if ( strLabel.length() == 0 ) @@ -552,55 +578,63 @@ strLogUrl = RHOCONF().getPath("syncserver"); String strQuery = strLogUrl + "client_log?" + "client_id=" + strClientID + "&device_pin=" + strDevicePin + "&log_name=" + RHOCONF().getString("logname"); - NetResponse( resp, getNet().pushFile( strQuery, LOGCONF().getLogFilePath(), &(rho::sync::CSyncThread::getSyncEngine()) ) ); + NetResponse( resp, getNet().pushFile( strQuery, LOGCONF().getLogFilePath(), &(rho::sync::CSyncThread::getSyncEngine()), null ) ); if ( !resp.isOK() ) { LOG(ERROR) + "send_log failed : network error"; return false; } return true; } -String CRhodesApp::addCallbackObject(unsigned long valObject, String strName) +String CRhodesApp::addCallbackObject(ICallbackObject* pCallbackObject, String strName) { int nIndex = -1; for (int i = 0; i < (int)m_arCallbackObjects.size(); i++) { if ( m_arCallbackObjects.elementAt(i) == 0 ) nIndex = i; } +// rho_ruby_holdValue(valObject); if ( nIndex == -1 ) { - m_arCallbackObjects.addElement(valObject); + m_arCallbackObjects.addElement(pCallbackObject); nIndex = m_arCallbackObjects.size()-1; }else - m_arCallbackObjects.setElementAt(valObject,nIndex); + m_arCallbackObjects.setElementAt(pCallbackObject,nIndex); String strRes = "__rho_object[" + strName + "]=" + convertToStringA(nIndex); return strRes; } -void CRhodesApp::delCallbackObject(unsigned long valObject) +void CRhodesApp::delCallbackObject(ICallbackObject* pCallbackObject) { for (int i = 0; i < (int)m_arCallbackObjects.size(); i++) { - if ( m_arCallbackObjects.elementAt(i) == valObject ) + if ( m_arCallbackObjects.elementAt(i) == pCallbackObject ) + { m_arCallbackObjects.setElementAt(0,i); +// rho_ruby_releaseValue(valObject); + } } } unsigned long CRhodesApp::getCallbackObject(int nIndex) { if ( nIndex < 0 || nIndex > m_arCallbackObjects.size() ) - return 0; + return rho_ruby_get_NIL(); - return m_arCallbackObjects.elementAt(nIndex); + ICallbackObject* pCallbackObject = m_arCallbackObjects.elementAt(nIndex); + if ( !pCallbackObject ) + return rho_ruby_get_NIL(); + + return pCallbackObject->getObjectValue(); } } } @@ -730,10 +764,29 @@ CHttpServer *serv = (CHttpServer *)httpContext; serv->send_response(serv->create_response("200 OK", headers, szBody)); #endif } +int rho_http_snprintf(char *buf, size_t buflen, const char *fmt, ...) +{ + va_list ap; + int n; + + if (buflen == 0) + return (0); + + va_start(ap, fmt); + n = vsnprintf(buf, buflen, fmt, ap); + va_end(ap); + + if (n < 0 || (size_t) n >= buflen) + n = buflen - 1; + buf[n] = '\0'; + + return (n); +} + void rho_rhodesapp_create(const char* szRootPath) { rho::common::CRhodesApp::Create(szRootPath); } @@ -757,13 +810,13 @@ return RHODESAPP().getStartUrl().c_str(); } const char* rho_rhodesapp_gethomeurl() { - return RHODESAPP().getHomeUrl().c_str(); + return RHODESAPP().getHomeUrl().c_str(); } - + const char* rho_rhodesapp_getoptionsurl() { return RHODESAPP().getOptionsUrl().c_str(); } @@ -796,22 +849,32 @@ void rho_rhodesapp_callDateTimeCallback(const char* strCallbackUrl, long lDateTime, const char* szData, int bCancel ) { RHODESAPP().callDateTimeCallback(strCallbackUrl, lDateTime, szData, bCancel != 0); } -void rho_rhodesapp_callAppActiveCallback() +void rho_rhodesapp_callAppActiveCallback(int nActive) { - RHODESAPP().callAppActiveCallback(); + RHODESAPP().callAppActiveCallback(nActive!=0); } void rho_rhodesapp_setViewMenu(unsigned long valMenu) { RHODESAPP().setViewMenu(valMenu); } const char* rho_rhodesapp_getappbackurl() { return RHODESAPP().getAppBackUrl().c_str(); +} + +const char* rho_ruby_getErrorText(int nError) +{ + return RHODESAPP().getRhoMessage( nError, "").c_str(); +} + +const char* rho_ruby_getMessageText(const char* szName) +{ + return "";//RHODESAPP().getRhoMessage( 0, szName).c_str(); } int rho_rhodesapp_isrubycompiler() { return 1;