platform/shared/common/RhodesApp.cpp in rhodes-3.5.1.12 vs platform/shared/common/RhodesApp.cpp in rhodes-5.5.0
- old
+ new
@@ -29,36 +29,31 @@
#include "common/IRhoClassFactory.h"
#include "common/RhoFile.h"
#include "common/RhoConf.h"
#include "common/RhoFilePath.h"
#include "common/RhoAppAdapter.h"
+#include "statistic/RhoProfiler.h"
#include "net/INetRequest.h"
-#include "sync/ClientRegister.h"
-#include "sync/SyncThread.h"
+#include "sync/RhoconnectClientManager.h"
#include "net/URI.h"
+#include "db/DBAdapter.h"
#include "net/HttpServer.h"
#include "ruby/ext/rho/rhoruby.h"
-#include "net/AsyncHttp.h"
#include "rubyext/WebView.h"
#include "rubyext/GeoLocation.h"
#include "common/app_build_configs.h"
#include "common/app_build_capabilities.h"
#include "unzip/unzip.h"
#include "common/Tokenizer.h"
+#include "api_generator/js_helpers.h"
+#include "api_generator/StringifyHelper.h"
+#include "coreapi/ext/shared/Application.h"
#include <algorithm>
-// licence lib
-#ifdef OS_ANDROID
-#include "../../../res/libs/motorolalicence/android/MotorolaLicence.h"
-#endif
-#ifdef OS_MACOSX
-#include "../../../res/libs/motorolalicence/iphone/MotorolaLicence.h"
-#endif
-
#ifdef OS_WINCE
#include <winsock.h>
#endif
using rho::net::HttpHeader;
@@ -69,40 +64,58 @@
void rho_map_location(char* query);
void rho_appmanager_load( void* httpContext, const char* szQuery);
void rho_db_init_attr_manager();
void rho_sys_app_exit();
void rho_sys_report_app_started();
+void rho_conf_show_log();
+bool rho_wmimpl_is_browser_ieforwm();
#ifdef OS_ANDROID
void rho_file_set_fs_mode(int mode);
#endif
}
-
+
+// Copy-paste from ApplicationBase.cpp
+static const char APP_EVENT_ACTIVATED[] = "Activated";
+static const char APP_EVENT_DEACTIVATED[] = "Deactivated";
+static const char APP_EVENT_UICREATED[] = "UICreated";
+static const char APP_EVENT_UIDESTROYED[] = "UIDestroyed";
+static const char APP_EVENT_SYNCUSERCHANGED[] = "SyncUserChanged";
+static const char APP_EVENT_CONFIGCONFLICT[] = "ConfigConflict";
+static const char APP_EVENT_DBMIGRATESOURCE[] = "DBMigrateSource";
+static const char APP_EVENT_UNINITIALIZED[] = "Uninitialized";
+static const char APP_EVENT_SCREEN_ON[] = "ScreenOn";
+static const char APP_EVENT_SCREEN_OFF[] = "ScreenOff";
+
+static const char APP_EVENT[] = "applicationEvent";
+static const char APP_EVENT_DATA[] = "eventData";
+
namespace rho {
namespace common{
IMPLEMENT_LOGCLASS(CRhodesApp,"RhodesApp");
-String CRhodesApp::m_strStartParameters;
+String CRhodesApp::m_strStartParameters, CRhodesApp::m_strStartParametersOriginal;
boolean CRhodesApp::m_bSecurityTokenNotPassed = false;
class CAppCallbacksQueue : public CThreadQueue
{
DEFINE_LOGCLASS;
public:
enum callback_t
{
- app_deactivated,
local_server_restart,
local_server_started,
ui_created,
- app_activated
+ screen_on,
+ app_activated,
+ app_deactivated
};
public:
CAppCallbacksQueue();
- CAppCallbacksQueue(LogCategory logCat);
+ //CAppCallbacksQueue(LogCategory logCat);
~CAppCallbacksQueue();
//void call(callback_t type);
friend class Command;
@@ -115,17 +128,29 @@
String toString() {return CAppCallbacksQueue::toString(type);}
};
private:
+ enum ui_created_state
+ {
+ ui_not_available,
+ ui_created_received,
+ ui_created_processed
+ };
+
void processCommand(IQueueCommand* pCmd);
+ void processUiCreated();
+ bool hasCommand(callback_t type);
+
static char const *toString(int type);
void callCallback(const String& strCallback);
private:
callback_t m_expected;
+ ui_created_state m_uistate;
+
Vector<int> m_commands;
boolean m_bFirstServerStart;
};
IMPLEMENT_LOGCLASS(CAppCallbacksQueue,"AppCallbacks");
@@ -141,31 +166,28 @@
return "APP-ACTIVATED";
case app_deactivated:
return "APP-DEACTIVATED";
case local_server_restart:
return "LOCAL-SERVER-RESTART";
+ case screen_on:
+ return "SCREEN-ON";
default:
return "UNKNOWN";
}
}
CAppCallbacksQueue::CAppCallbacksQueue()
- :CThreadQueue(), m_expected(local_server_started), m_bFirstServerStart(true)
+ :CThreadQueue(), m_expected(local_server_started), m_uistate(ui_not_available), m_bFirstServerStart(true)
{
CThreadQueue::setLogCategory(getLogCategory());
setPollInterval(QUEUE_POLL_INTERVAL_INFINITE);
start(epNormal);
}
CAppCallbacksQueue::~CAppCallbacksQueue()
{
}
-/*
-void CAppCallbacksQueue::call(CAppCallbacksQueue::callback_t type)
-{
- addQueueCommand(new Command(type));
-}*/
void CAppCallbacksQueue::callCallback(const String& strCallback)
{
if ( !rho_ruby_is_started() )
return;
@@ -201,72 +223,104 @@
if ( !resp.isOK() )
LOG(ERROR) + strCallback + " call failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
}
}
+bool CAppCallbacksQueue::hasCommand(callback_t type)
+{
+ for( int i = 0; i < (int)m_commands.size() ; i++)
+ {
+ if ( m_commands.elementAt(i) == type )
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
void CAppCallbacksQueue::processCommand(IQueueCommand* pCmd)
{
Command *cmd = (Command *)pCmd;
if (!cmd)
return;
-
-/*
- if (cmd->type < m_expected)
+
+ LOG(INFO) + toString(cmd->type) + " is received ++++++++++++++++++++++++++++";
+
+ if (cmd->type == ui_created)
{
- LOG(ERROR) + "received command " + toString(cmd->type) + " which is less than expected "+toString(m_expected)+" - ignore it";
- return;
+ LOG(INFO) + "m_uistate: " + (int)m_uistate;
+
+ if (m_uistate != ui_not_available)
+ return;
+ m_uistate = ui_created_received;
}
-*/
+
if ( m_expected == app_deactivated && cmd->type == app_activated )
{
- LOG(INFO) + "received duplicate activate skip it";
+ LOG(INFO) + "received duplicate app_activated - skip it";
return;
}
if ( m_expected == local_server_restart )
{
if ( cmd->type != local_server_started )
+ {
+ LOG(INFO) + "Restart local server ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^";
RHODESAPP().restartLocalServer(*this);
+ sleep(50);
+ LOG(INFO) + "Continue after server restart =======================================";
+ }
else
LOG(INFO) + "Local server restarted before activate.Do not restart it again.";
m_expected = local_server_started;
}
+
+ Vector<int> commandsLocalCopy;
+
+ { //Command queue lock scope
+ synchronized(getCommandLock());
- if (cmd->type > m_expected)
- {
- boolean bDuplicate = false;
- for( int i = 0; i < (int)m_commands.size() ; i++)
- {
- if ( m_commands.elementAt(i) == cmd->type )
- {
- bDuplicate = true;
- break;
- }
- }
- if ( bDuplicate )
- {
- LOG(INFO) + "Received duplicate command " + toString(cmd->type) + "skip it";
- }else
- {
- // Don't do that now
- LOG(INFO) + "Received command " + toString(cmd->type) + " which is greater than expected (" + toString(m_expected) + ") - postpone it";
- m_commands.push_back(cmd->type);
- std::sort(m_commands.begin(), m_commands.end());
- }
- return;
+ if (cmd->type > m_expected)
+ {
+ if ( hasCommand(cmd->type) )
+ {
+ LOG(INFO) + "Received duplicate command " + toString(cmd->type) + "skip it";
+ return;
+ }else
+ {
+ // Don't do that now
+ LOG(INFO) + "Received command " + toString(cmd->type) + " which is greater than expected (" + toString(m_expected) + ") - postpone it";
+
+ if (cmd->type == app_deactivated && m_expected != local_server_started)
+ {
+ m_commands.clear();
+ m_commands.push_back(cmd->type);
+ }
+ else
+ {
+ m_commands.push_back(cmd->type);
+ std::sort(m_commands.begin(), m_commands.end());
+ return;
+ }
+ }
+ }
+ else
+ {
+ m_commands.insert(m_commands.begin(), cmd->type);
+ }
+
+ m_commands.swap( commandsLocalCopy );
+
+ //Command queue lock scope
}
- 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)
+ for (Vector<int>::const_iterator it = commandsLocalCopy.begin(), lim = commandsLocalCopy.end(); it != lim; ++it)
{
int type = *it;
- LOG(INFO) + "process command: " + toString(type);
+ LOG(INFO) + "process command: " + toString(type) + "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<";
switch (type)
{
case app_deactivated:
#if !defined( WINDOWS_PLATFORM )
m_expected = local_server_restart;
@@ -285,28 +339,69 @@
m_expected = app_activated;
rho_sys_report_app_started();
break;
case ui_created:
+ if (m_uistate != ui_created_processed)
{
- callCallback("/system/uicreated");
+ processUiCreated();
m_expected = app_activated;
}
break;
case app_activated:
{
- callCallback("/system/activateapp");
+ if ( m_uistate == ui_created_received )
+ {
+ processUiCreated();
+ }
+ if (!RHODESAPP().getApplicationEventReceiver()->onAppStateChange(rho::common::applicationStateActivated))
+ {
+ callCallback("/system/activateapp");
+ }
m_expected = app_deactivated;
}
break;
+ case screen_on:
+ RHODESAPP().getApplicationEventReceiver()->onDeviceScreenEvent(rho::common::screenOn);
+ break;
}
- //if (type < app_activated && type != app_deactivated)
- // m_expected = (callback_t)(type + 1);
}
- m_commands.clear();
+ //m_commands.clear();
}
+void CAppCallbacksQueue::processUiCreated()
+{
+ rho::String startPath = RHOCONF().getString("start_path");
+
+ // handle security token validation
+ #ifndef OS_WP8
+ rho::String invalidSecurityTokenStartPath = RHOCONF().getString("invalid_security_token_start_path");
+
+ if (RHODESAPP().isSecurityTokenNotPassed()) {
+ if (invalidSecurityTokenStartPath.length() > 0) {
+ startPath = invalidSecurityTokenStartPath;
+ } else {
+ // exit from application - old way
+ LOGC(FATAL, "EROOR" ) + "processApplicationEvent: security_token is not passed - application will closed";
+ rho_sys_app_exit();
+ }
+ }
+ #endif
+
+ // at this point JS app is unlikely to set its own handler, just navigate to overriden start path
+ if (!RHODESAPP().getApplicationEventReceiver()->onUIStateChange(rho::common::UIStateCreated))
+ {
+ if ( rho_ruby_is_started() )
+ callCallback("/system/uicreated");
+#if !defined(APP_BUILD_CAPABILITY_SHARED_RUNTIME) || !defined(OS_ANDROID)
+ else
+ rho_webview_navigate(startPath.c_str(), 0);
+#endif
+ }
+ m_uistate = ui_created_processed;
+}
+
/*static*/ CRhodesApp* CRhodesApp::Create(const String& strRootPath, const String& strUserPath, const String& strRuntimePath)
{
if ( m_pInstance != null)
return (CRhodesApp*)m_pInstance;
@@ -319,88 +414,182 @@
{
if ( m_pInstance )
delete m_pInstance;
m_pInstance = 0;
-
-
-
}
CRhodesApp::CRhodesApp(const String& strRootPath, const String& strUserPath, const String& strRuntimePath)
:CRhodesAppBase(strRootPath, strUserPath, strRuntimePath),
- m_appPushMgr(*this), m_networkStatusReceiver(m_mxNetworkStatus)
+ m_networkStatusReceiver(m_mxNetworkStatus)
{
m_bExit = false;
m_bDeactivationMode = false;
m_bRestartServer = false;
//m_activateCounter = 0;
- m_pExtManager = 0;
+ //m_pExtManager = 0;
m_pNetworkStatusMonitor = 0;
- m_appCallbacksQueue = new CAppCallbacksQueue();
-
+ m_appCallbacksQueue = new CAppCallbacksQueue();
+
#if defined(WINDOWS_PLATFORM)
//initializing winsock
WSADATA WsaData;
m_cameraOpened = false;
int result = WSAStartup(MAKEWORD(2,2),&WsaData);
#endif
initAppUrls();
- LOGCONF().initRemoteLog();
+ if(!m_isJSFSApp)
+ initHttpServer();
- initHttpServer();
-
getSplashScreen().init();
}
void CRhodesApp::startApp()
{
start(epNormal);
}
-void CRhodesApp::run()
+extern "C" void Init_Extensions(void);
+
+void CRhodesApp::RhoJsStart()
{
- LOG(INFO) + "Starting RhodesApp main routine...";
- RhoRubyStart();
- rubyext::CGeoLocation::Create();
+ LOG(INFO) + "Starting pure JS application...";
- //rho_db_init_attr_manager();
+ const char* szBlobPath = getBlobsDirPath().c_str();
+ const char* szUserPath = rho_native_rhodbpath();
+ LOG(INFO) + "Init_RhoBlobs:" + szBlobPath;
- LOG(INFO) + "Starting sync engine...";
- sync::CSyncThread::Create();
+ CRhoFile::recursiveCreateDir(szBlobPath, szUserPath);
- LOG(INFO) + "RhoRubyInitApp...";
- RhoRubyInitApp();
- rho_ruby_call_config_conflicts();
- RHOCONF().conflictsResolved();
+ PROF_START("EXTENSIONS_INIT");
+ Init_Extensions();
+ PROF_STOP("EXTENSIONS_INIT");
- while (!m_bExit) {
- m_httpServer->run();
- if (m_bExit)
- break;
+ void *dbObj = NULL;
- if ( !m_bRestartServer )
+ rho::String partName = rho::db::CDBAdapter::USER_PARTITION_NAME();
+ rho::String dbPath = rho::Application::databaseFilePath(partName.c_str());
+
+ rho_db_open(dbPath.c_str(), partName.c_str(), &dbObj);
+
+ //rho_webview_navigate(RHOCONF().getString("start_path").c_str(), 0);
+}
+
+void CRhodesApp::run()
+{
+ LOG(INFO) + "Starting RhodesApp main routine...";
+#ifndef RHO_NO_RUBY_API
+ if (!isJSApplication())
+ {
+ RhoRubyStart();
+ rubyext::CGeoLocation::Create();
+ }
+ else
+#endif
+ RhoJsStart();
+
+
+ if ( sync::RhoconnectClientManager::haveRhoconnectClientImpl() ) {
+ LOG(INFO) + "Starting sync engine...";
+ sync::RhoconnectClientManager::syncThreadCreate();
+ }
+#ifndef RHO_NO_RUBY_API
+ if (!isJSApplication())
+ {
+ LOG(INFO) + "RhoRubyInitApp...";
+ RhoRubyInitApp();
+
+ HashtablePtr<String,Vector<String>* >& mapConflicts = RHOCONF().getConflicts();
+ bool handled = mapConflicts.size()==0;
+
+ if (!handled)
{
- LOG(INFO) + "RhodesApp thread wait.";
- wait(-1);
+ handled = m_applicationEventReceiver.onReinstallConfigUpdate(mapConflicts);
}
- m_bRestartServer = false;
+ if (!handled)
+ {
+ rho_ruby_call_config_conflicts();
+ }
}
+#endif
+ RHOCONF().conflictsResolved();
+ PROF_CREATE_COUNTER("READ_FILE");
+ PROF_CREATE_COUNTER("LOW_FILE");
+ if(m_isJSFSApp)
+ RHODESAPP().notifyLocalServerStarted();
+
+#ifdef OS_MACOSX
+ bool shouldRunDirectQueue = true;
+ net::CDirectHttpRequestQueue directQueue(*m_httpServer, *this );
+
+ if (RHOCONF().isExist("ios_direct_local_requests")) {
+ shouldRunDirectQueue = RHOCONF().getBool("ios_direct_local_requests");
+ }
+#endif
+
+
+ while (!m_bExit) {
+ if(!m_isJSFSApp)
+ {
+#ifdef OS_MACOSX
+ if ( shouldRunDirectQueue )
+ {
+ directQueue.run();
+ }
+ else
+#endif
+ {
+ m_httpServer->run();
+ }
+
+ }
+ else
+ {
+ LOG(INFO) + "RhodesApp thread wait.";
+ wait(-1);
+ }
+
+ if (m_bExit)
+ break;
+
+ if ( !m_bRestartServer )
+ {
+ LOG(INFO) + "RhodesApp thread wait.";
+ wait(-1);
+ }
+ m_bRestartServer = false;
+ }
+
+ PROF_DESTROY_COUNTER("LOW_FILE");
+ PROF_DESTROY_COUNTER("READ_FILE");
+
LOG(INFO) + "RhodesApp thread shutdown";
getExtManager().close();
- rubyext::CGeoLocation::Destroy();
- sync::CClientRegister::Destroy();
- sync::CSyncThread::Destroy();
- net::CAsyncHttp::Destroy();
+ if (!isJSApplication())
+ {
+ rubyext::CGeoLocation::Destroy();
+ }
- RhoRubyStop();
+ if ( sync::RhoconnectClientManager::haveRhoconnectClientImpl() )
+ {
+ sync::RhoconnectClientManager::clientRegisterDestroy();
+ sync::RhoconnectClientManager::syncThreadDestroy();
+ }
+
+ db::CDBAdapter::closeAll();
+#ifndef RHO_NO_RUBY_API
+ if (!isJSApplication())
+ {
+ RhoRubyStop();
+ }
+#endif
}
CRhodesApp::~CRhodesApp(void)
{
stopApp();
@@ -408,50 +597,56 @@
LOGCONF().closeRemoteLog();
#ifdef OS_WINCE
WSACleanup();
#endif
-
}
boolean CRhodesApp::callTimerCallback(const String& strUrl, const String& strData)
{
String strBody = "rho_callback=1";
if ( strData.length() > 0 )
strBody += "&" + strData;
-
- String strReply;
- return m_httpServer->call_ruby_method(strUrl, strBody, strReply);
+
+ callCallbackWithData(strUrl, "", strData, false);
+ return true;
}
void CRhodesApp::restartLocalServer(common::CThreadQueue& waitThread)
{
LOG(INFO) + "restart local server.";
m_bRestartServer = true;
- m_httpServer->stop();
+ if(!m_isJSFSApp)
+ {
+ m_httpServer->stop();
+ }else
+ RHODESAPP().notifyLocalServerStarted();
+
stopWait();
}
void CRhodesApp::stopApp()
{
+ if (m_bExit)
+ return;
+
m_appCallbacksQueue->stop(1000);
- if (!m_bExit && rho_ruby_is_started())
+ if (!m_bExit)
{
m_bExit = true;
- m_httpServer->stop();
+ if(!m_isJSFSApp)
+ m_httpServer->stop();
stopWait();
- stop(2000);
+ stop(4000);
}
#ifdef OS_ANDROID
// Switch Android libc hooks to FS only mode
rho_file_set_fs_mode(0);
#endif
-
-// net::CAsyncHttp::Destroy();
}
class CRhoCallbackCall
{
String m_strCallback, m_strBody;
@@ -474,31 +669,47 @@
rho_rhodesapp_call_in_thread(new CRhoCallbackCall(strCallback, strBody ) );
}
static void callback_activateapp(void *arg, String const &strQuery)
{
- rho_ruby_activateApp();
+#ifndef RHO_NO_RUBY_API
+ if (!RHODESAPP().isJSApplication())
+ rho_ruby_activateApp();
+#endif
+
String strMsg;
rho_http_sendresponse(arg, strMsg.c_str());
}
static void callback_deactivateapp(void *arg, String const &strQuery)
{
- rho_ruby_deactivateApp();
+#ifndef RHO_NO_RUBY_API
+ if (!RHODESAPP().isJSApplication())
+ rho_ruby_deactivateApp();
+#endif
+
String strMsg;
rho_http_sendresponse(arg, strMsg.c_str());
}
static void callback_uicreated(void *arg, String const &strQuery)
{
- rho_ruby_uiCreated();
+#ifndef RHO_NO_RUBY_API
+ if (!RHODESAPP().isJSApplication())
+ rho_ruby_uiCreated();
+#endif
+
rho_http_sendresponse(arg, "");
}
static void callback_uidestroyed(void *arg, String const &strQuery)
{
- rho_ruby_uiDestroyed();
+#ifndef RHO_NO_RUBY_API
+ if (!RHODESAPP().isJSApplication())
+ rho_ruby_uiDestroyed();
+#endif
+
rho_http_sendresponse(arg, "");
}
static void callback_loadserversources(void *arg, String const &strQuery)
{
@@ -526,18 +737,24 @@
m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::ui_created));
}
void CRhodesApp::callUiDestroyedCallback()
{
- if ( m_bExit || !rho_ruby_is_started() )
+ if ( m_bExit/* || !rho_ruby_is_started()*/ )
return;
-
- String strUrl = m_strHomeUrl + "/system/uidestroyed";
- NetResponse resp = getNetRequest().pullData( strUrl, null );
- if ( !resp.isOK() )
+
+ if (!RHODESAPP().getApplicationEventReceiver()->onUIStateChange(rho::common::UIStateDestroyed))
{
- LOG(ERROR) + "UI destroy callback failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
+ if ( rho_ruby_is_started() )
+ {
+ String strUrl = m_strHomeUrl + "/system/uidestroyed";
+ NetResponse resp = getNetRequest().pullData( strUrl, null );
+ if ( !resp.isOK() )
+ {
+ LOG(ERROR) + "UI destroy callback failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
+ }
+ }
}
}
void CRhodesApp::callAppActiveCallback(boolean bActive)
{
@@ -568,31 +785,37 @@
// However, blocking UI thread can cause problem with API refering to UI (such as WebView.navigate etc)
// To fix this problem, new mode 'deactivation' introduced. When this mode active, no UI operations allowed.
// All such operation will throw exception in ruby code when calling in 'deactivate' mode.
m_bDeactivationMode = true;
m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::app_deactivated));
-
- if ( rho_ruby_is_started() )
+
+ // TODO: Support stop_local_server command to be parsed from callback result
+ if (!RHODESAPP().getApplicationEventReceiver()->onAppStateChange(rho::common::applicationStateDeactivated))
{
- String strUrl = m_strHomeUrl + "/system/deactivateapp";
- NetResponse resp = getNetRequest().pullData( strUrl, null );
- if ( !resp.isOK() )
+#ifndef RHO_NO_RUBY_API
+ if ( rho_ruby_is_started() )
{
- LOG(ERROR) + "deactivate app failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
- }else
- {
- const char* szData = resp.getCharData();
- boolean bStop = szData && strcmp(szData,"stop_local_server") == 0;
-
- if (bStop)
+ String strUrl = m_strHomeUrl + "/system/deactivateapp";
+ NetResponse resp = getNetRequest().pullData( strUrl, null );
+ if ( !resp.isOK() )
{
- #if !defined( WINDOWS_PLATFORM )
- LOG(INFO) + "Stopping local server.";
- m_httpServer->stop();
- #endif
+ LOG(ERROR) + "deactivate app failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
+ }else
+ {
+ const char* szData = resp.getCharData();
+ boolean bStop = szData && strcmp(szData,"stop_local_server") == 0;
+
+ if (bStop)
+ {
+ #if !defined( WINDOWS_PLATFORM )
+ LOG(INFO) + "Stopping local server.";
+ m_httpServer->stop();
+ #endif
+ }
}
}
+#endif
}
m_bDeactivationMode = false;
}
}
@@ -611,14 +834,27 @@
{
strBody += "&status=fail";
}
strBody += "&rho_callback=1";
- //getNetRequest().pushData( strCallbackUrl, strBody, null );
+
runCallbackInThread(strCallbackUrl, strBody);
}
+//Due to the Multithreading issue callback was causing problem. That has been fixed in this.
+#if ( !defined(OS_MACOSX) && (defined(OS_WINDOWS_DESKTOP) || defined(RHODES_EMULATOR)))
+String g_strCallbackUrl;
+String g_strBody;
+ DWORD WINAPI CallbackExecThread( LPVOID lpParam )
+ {
+ if ( !rho_ruby_is_started() )
+ return 0;
+ getNetRequest().pushData( g_strCallbackUrl, g_strBody, null );
+ return 0;
+ }
+
+#endif
void CRhodesApp::callCallbackWithData(String strCallbackUrl, String strBody, const String& strCallbackData, bool bWaitForResponse)
{
strCallbackUrl = canonicalizeRhoUrl(strCallbackUrl);
LOG(TRACE) + "Call back URL: " + strCallbackUrl;
@@ -631,13 +867,47 @@
strBody += "&";
strBody += strCallbackData;
}
+#if ( !defined(OS_MACOSX) && (defined(OS_WINDOWS_DESKTOP) || defined(RHODES_EMULATOR)) )
+ g_strCallbackUrl = strCallbackUrl;
+ g_strBody = strBody;
+#endif
+
if (bWaitForResponse)
getNetRequest().pushData( strCallbackUrl, strBody, null );
else
+ {
+#if ( !defined(OS_MACOSX) && (defined(OS_WINDOWS_DESKTOP) || defined(RHODES_EMULATOR)) )
+ LOG(INFO) + strCallbackUrl + "in a Windows Specific Thread";
+ CloseHandle(::CreateThread(NULL,0,CallbackExecThread,NULL,0,NULL));
+#else
+ runCallbackInThread(strCallbackUrl, strBody);
+#endif
+ }
+}
+
+void CRhodesApp::callCallbackProcWithData(unsigned long oRubyCallbackProc, String strBody, const String& strCallbackData, bool bWaitForResponse)
+{
+ strBody += "&rho_callback=1";
+
+ if (strCallbackData.length() > 0 )
+ {
+ if ( !String_startsWith( strCallbackData, "&" ) )
+ strBody += "&";
+
+ strBody += strCallbackData;
+ }
+
+ String strCallbackUrl = "/system/call_ruby_proc_callback?";
+ strCallbackUrl += convertToStringA(oRubyCallbackProc);
+ strCallbackUrl = canonicalizeRhoUrl(strCallbackUrl);
+
+ if (bWaitForResponse)
+ getNetRequest().pushData( strCallbackUrl, strBody, null );
+ else
runCallbackInThread(strCallbackUrl, strBody);
}
extern "C" VALUE rjson_tokener_parse(const char *str, char** pszError );
@@ -645,10 +915,11 @@
{
String m_strJson;
public:
CJsonResponse(const String& strJson) : m_strJson(strJson) { }
CJsonResponse(const char* szJson) : m_strJson(szJson) { }
+#ifndef RHO_NO_RUBY_API
virtual unsigned long getObjectValue()
{
char* szError = 0;
unsigned long valBody = rjson_tokener_parse(m_strJson.c_str(), &szError);
if ( valBody != 0 )
@@ -658,10 +929,17 @@
if ( szError )
free(szError);
return rho_ruby_get_NIL();
}
+#else
+ virtual unsigned long getObjectValue()
+ {
+ return 0;
+ }
+
+#endif
};
void CRhodesApp::callCallbackWithJsonBody( const char* szCallback, const char* szCallbackBody, const char* szCallbackData, bool bWaitForResponse)
{
String strBody;
@@ -669,11 +947,11 @@
callCallbackWithData(szCallback, strBody, szCallbackData, bWaitForResponse );
}
void CRhodesApp::callCameraCallback(String strCallbackUrl, const String& strImagePath,
- const String& strError, boolean bCancel )
+ const String& strError, boolean bCancel )
{
strCallbackUrl = canonicalizeRhoUrl(strCallbackUrl);
String strBody;
if ( bCancel || strError.length() > 0 )
{
@@ -682,10 +960,11 @@
else
strBody = "status=error&message=" + strError;
}else
strBody = "status=ok&image_uri=db%2Fdb-files%2F" + strImagePath;
+
strBody += "&rho_callback=1";
getNetRequest().pushData( strCallbackUrl, strBody, null );
}
void CRhodesApp::callSignatureCallback(String strCallbackUrl, const String& strSignaturePath,
@@ -744,32 +1023,45 @@
getNetRequest().pushData( strCallbackUrl, strBody, null );
}
static void callback_syncdb(void *arg, String const &/*query*/ )
{
- rho_sync_doSyncAllSources(1,"",false);
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+// rho_sync_doSyncAllSources(1,"",false);
+ rho::sync::RhoconnectClientManager::doSyncAllSources(1,"",false);
+ }
rho_http_sendresponse(arg, "");
}
static void callback_dosync(void *arg, String const &/*query*/ )
{
- rho_sync_doSyncAllSources(1,"",false);
- rho_http_sendresponse(arg, "ok");
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+// rho_sync_doSyncAllSources(1,"",false);
+ rho::sync::RhoconnectClientManager::doSyncAllSources(1,"",false);
+
+ }
+ rho_http_sendresponse(arg, "ok");
}
static void callback_dosync_source(void *arg, String const &strQuery )
{
- size_t nPos = strQuery.find("srcName=");
- if ( nPos != String::npos )
- {
- String strSrcName = strQuery.substr(nPos+8);
- LOG(INFO) + "srcName = '" + strSrcName + "'";
- rho_sync_doSyncSourceByName(strSrcName.c_str());
- } else {
- LOG(WARNING) + "Unable to find 'srcName' parameter";
- }
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl())
+ {
+ size_t nPos = strQuery.find("srcName=");
+ if ( nPos != String::npos )
+ {
+ String strSrcName = strQuery.substr(nPos+8);
+ LOG(INFO) + "srcName = '" + strSrcName + "'";
+// rho_sync_doSyncSourceByName(strSrcName.c_str());
+ rho::sync::RhoconnectClientManager::doSyncSourceByName(strSrcName.c_str());
+ } else {
+ LOG(WARNING) + "Unable to find 'srcName' parameter";
+ }
+ }
+
rho_http_sendresponse(arg, "ok");
+
}
static void callback_logger(void *arg, String const &query )
{
int nLevel = 0;
@@ -830,10 +1122,11 @@
}
static void callback_getrhomessage(void *arg, String const &strQuery)
{
String strMsg;
+#ifndef RHO_NO_RUBY_API
size_t nErrorPos = strQuery.find("error=");
if ( nErrorPos != String::npos )
{
String strError = strQuery.substr(nErrorPos+6);
int nError = atoi(strError.c_str());
@@ -846,11 +1139,11 @@
{
String strName = strQuery.substr(nMsgIdPos+6);
strMsg = rho_ruby_internal_getMessageText(strName.c_str());
}
}
-
+#endif
rho_http_sendresponse(arg, strMsg.c_str());
}
const String& CRhodesApp::getRhoMessage(int nError, const char* szName)
{
@@ -879,135 +1172,193 @@
return m_strRhoMessage;
}
static void callback_logged_in(void *arg, String const &strQuery)
{
- rho_http_sendresponse(arg, rho_sync_logged_in() ? "true" : "false");
+ //rho_http_sendresponse(arg, rho_sync_logged_in() ? "true" : "false");
+ bool haveclient = rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl();
+ rho_http_sendresponse(arg, (haveclient && rho::sync::RhoconnectClientManager::logged_in()) ? "true" : "false");
}
static void callback_logout(void *arg, String const &strQuery)
{
- rho_sync_logout();
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+ rho::sync::RhoconnectClientManager::logout();
+ //rho_sync_logout();
+ }
rho_http_sendresponse(arg, "ok");
}
static void callback_stop_sync(void *arg, String const &strQuery)
{
- rho_sync_stop();
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+ rho::sync::RhoconnectClientManager::stop();
+ //rho_sync_stop();
+ }
rho_http_sendresponse(arg, "ok");
}
static void callback_set_pollinterval(void *arg, String const &strQuery)
{
- int nInterval = 0;
+ int nInterval = 0;
- size_t nPos = strQuery.find("interval=");
- if ( nPos != String::npos )
- {
- String strInterval = strQuery.substr(nPos+9);
- nInterval = atoi(strInterval.c_str());
- } else {
- LOG(WARNING) + "Unable to find 'interval' parameter";
- }
- nInterval = rho_sync_set_pollinterval(nInterval);
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+
+
+ size_t nPos = strQuery.find("interval=");
+ if ( nPos != String::npos )
+ {
+ String strInterval = strQuery.substr(nPos+9);
+ nInterval = atoi(strInterval.c_str());
+ } else {
+ LOG(WARNING) + "Unable to find 'interval' parameter";
+ }
+ // nInterval = rho_sync_set_pollinterval(nInterval);
+ nInterval = rho::sync::RhoconnectClientManager::set_pollinterval(nInterval);
+
+ }
rho_http_sendresponse(arg, convertToStringA(nInterval).c_str());
}
static void callback_get_pollinterval(void *arg, String const &strQuery)
{
- rho_http_sendresponse(arg, convertToStringA(rho_sync_get_pollinterval()).c_str());
+ String interval = "";
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+ interval = convertToStringA(rho::sync::RhoconnectClientManager::get_pollinterval());
+ }
+
+// rho_http_sendresponse(arg, convertToStringA(rho_sync_get_pollinterval()).c_str());
+ rho_http_sendresponse(arg, interval.c_str());
}
static void callback_set_syncserver(void *arg, String const &strQuery)
{
- String strSyncserver = "";
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
- size_t nPos = strQuery.find("syncserver=");
- if ( nPos != String::npos )
- {
- strSyncserver = rho::net::URI::urlDecode(strQuery.substr(nPos+11));
- } else {
- LOG(WARNING) + "Unable to find 'syncserver' parameter";
- }
- rho_sync_set_syncserver(strSyncserver.c_str());
+ String strSyncserver = "";
+
+ size_t nPos = strQuery.find("syncserver=");
+ if ( nPos != String::npos )
+ {
+ strSyncserver = rho::net::URI::urlDecode(strQuery.substr(nPos+11));
+ } else {
+ LOG(WARNING) + "Unable to find 'syncserver' parameter";
+ }
+ // rho_sync_set_syncserver(strSyncserver.c_str());
+ rho::sync::RhoconnectClientManager::set_syncserver(strSyncserver.c_str());
+ }
rho_http_sendresponse(arg, "ok");
}
static void callback_set_pagesize(void *arg, String const &strQuery)
{
int nSize = 0;
+ int nOldSize = 0;
+
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
- size_t nPos = strQuery.find("pagesize=");
- if ( nPos != String::npos )
- {
- String strSize = strQuery.substr(nPos+9);
- nSize = atoi(strSize.c_str());
- } else {
- LOG(WARNING) + "Unable to find 'pagesize' parameter";
- }
- int nOldSize = rho_sync_get_pagesize();
- rho_sync_set_pagesize(nSize);
+ size_t nPos = strQuery.find("pagesize=");
+ if ( nPos != String::npos )
+ {
+ String strSize = strQuery.substr(nPos+9);
+ nSize = atoi(strSize.c_str());
+ } else {
+ LOG(WARNING) + "Unable to find 'pagesize' parameter";
+ }
+
+ nOldSize = rho::sync::RhoconnectClientManager::get_pagesize();
+ rho::sync::RhoconnectClientManager::set_pagesize(nSize);
+
+ // int nOldSize = rho_sync_get_pagesize();
+ // rho_sync_set_pagesize(nSize);
+
+ }
+
rho_http_sendresponse(arg, convertToStringA(nOldSize).c_str());
}
static void callback_get_pagesize(void *arg, String const &strQuery)
{
- rho_http_sendresponse(arg, convertToStringA(rho_sync_get_pagesize()).c_str());
+ int size = 0;
+
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+ size = rho::sync::RhoconnectClientManager::get_pagesize();
+ }
+// rho_http_sendresponse(arg, convertToStringA(rho_sync_get_pagesize()).c_str());
+ rho_http_sendresponse(arg, convertToStringA(size).c_str());
}
static void callback_get_lastsync_objectcount(void *arg, String const &strQuery)
{
int nSrcId = -1;
int nCount = -1;
+
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
- size_t nPos = strQuery.find("srcName=");
- if ( nPos != String::npos )
- {
- String strSrcId = strQuery.substr(nPos+8);
- LOG(INFO) + "srcName = '" + strSrcId + "'";
- nSrcId = atoi(strSrcId.c_str());
- nCount = rho_sync_get_lastsync_objectcount(nSrcId);
- } else {
- LOG(WARNING) + "Unable to find 'srcName' parameter";
- }
+ size_t nPos = strQuery.find("srcName=");
+ if ( nPos != String::npos )
+ {
+ String strSrcId = strQuery.substr(nPos+8);
+ LOG(INFO) + "srcName = '" + strSrcId + "'";
+ nSrcId = atoi(strSrcId.c_str());
+ // nCount = rho_sync_get_lastsync_objectcount(nSrcId);
+ nCount = rho::sync::RhoconnectClientManager::get_lastsync_objectcount(nSrcId);
+ } else {
+ LOG(WARNING) + "Unable to find 'srcName' parameter";
+ }
+ }
rho_http_sendresponse(arg, convertToStringA(nCount).c_str());
}
static void callback_is_syncing(void *arg, String const &strQuery)
{
- rho_http_sendresponse(arg, rho_sync_issyncing() ? "true" : "false");
+ bool haveclient = rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl();
+ // rho_http_sendresponse(arg, rho_sync_issyncing() ? "true" : "false");
+ rho_http_sendresponse(arg, ( haveclient && rho::sync::RhoconnectClientManager::issyncing() ) ? "true" : "false");
}
static void callback_enable_status_popup(void *arg, String const &strQuery)
{
- size_t nPos = strQuery.find("enable=");
- if ( nPos != String::npos )
- {
- String strEnable = strQuery.substr(nPos+7);
- rho_sync_enable_status_popup(strEnable == "true" ? 2 : 0);
- } else {
- LOG(WARNING) + "Unable to find 'enable' parameter";
- }
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+
+ size_t nPos = strQuery.find("enable=");
+ if ( nPos != String::npos )
+ {
+ String strEnable = strQuery.substr(nPos+7);
+ // rho_sync_enable_status_popup(strEnable == "true" ? 2 : 0);
+ rho::sync::RhoconnectClientManager::enable_status_popup(strEnable == "true" ? 2 : 0);
+ } else {
+ LOG(WARNING) + "Unable to find 'enable' parameter";
+ }
+ }
rho_http_sendresponse(arg, "ok");
}
static void callback_set_threaded_mode(void *arg, String const &strQuery)
{
- size_t nPos = strQuery.find("threaded=");
- if ( nPos != String::npos )
- {
- String strThreaded = strQuery.substr(nPos+9);
- rho_sync_set_threaded_mode(strThreaded == "true" ? 2 : 0);
- } else {
- LOG(WARNING) + "Unable to find 'threaded' parameter";
- }
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+
+ size_t nPos = strQuery.find("threaded=");
+ if ( nPos != String::npos )
+ {
+ String strThreaded = strQuery.substr(nPos+9);
+ // rho_sync_set_threaded_mode(strThreaded == "true" ? 2 : 0);
+ rho::sync::RhoconnectClientManager::set_threaded_mode(strThreaded == "true" ? 2 : 0);
+ } else {
+ LOG(WARNING) + "Unable to find 'threaded' parameter";
+ }
+ }
rho_http_sendresponse(arg, "ok");
}
static void callback_register_push(void *arg, String const &strQuery)
{
- rho_sync_register_push();
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+ // rho_sync_register_push();
+ rho::sync::RhoconnectClientManager::register_push();
+
+ }
rho_http_sendresponse(arg, "ok");
}
static void callback_set_source_property(void *arg, String const &strQuery)
{
@@ -1015,18 +1366,22 @@
rho_http_sendresponse(arg, "ok");
}
static void callback_set_ssl_verify_peer(void *arg, String const &strQuery)
{
- size_t nPos = strQuery.find("verify=");
- if ( nPos != String::npos )
- {
- String strVerify = strQuery.substr(nPos+7);
- rho_sync_set_ssl_verify_peer(strVerify == "true" ? 2 : 0);
- } else {
- LOG(WARNING) + "Unable to find 'verify' parameter";
- }
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+
+ size_t nPos = strQuery.find("verify=");
+ if ( nPos != String::npos )
+ {
+ String strVerify = strQuery.substr(nPos+7);
+ // rho_sync_set_ssl_verify_peer(strVerify == "true" ? 2 : 0);
+ rho::sync::RhoconnectClientManager::set_ssl_verify_peer(strVerify == "true" ? 2 : 0);
+ } else {
+ LOG(WARNING) + "Unable to find 'verify' parameter";
+ }
+ }
rho_http_sendresponse(arg, "ok");
}
static void callback_update_blob_attribs(void *arg, String const &strQuery)
{
@@ -1034,18 +1389,24 @@
rho_http_sendresponse(arg, "ok");
}
static void callback_set_objectnotify_url(void *arg, String const &strQuery)
{
- size_t nPos = strQuery.find("url=");
- if ( nPos != String::npos )
- {
- String strUrl = strQuery.substr(nPos+4);
- rho_sync_setobjectnotify_url(strUrl.c_str());
- } else {
- LOG(WARNING) + "Unable to find 'url' parameter";
- }
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+
+ size_t nPos = strQuery.find("url=");
+ if ( nPos != String::npos )
+ {
+ String strUrl = strQuery.substr(nPos+4);
+ // rho_sync_setobjectnotify_url(strUrl.c_str());
+ rho::sync::RhoconnectClientManager::setobjectnotify_url(strUrl.c_str());
+ } else {
+ LOG(WARNING) + "Unable to find 'url' parameter";
+ }
+
+ }
+
rho_http_sendresponse(arg, "ok");
}
static void callback_add_objectnotify(void *arg, String const &strQuery)
{
@@ -1053,11 +1414,14 @@
rho_http_sendresponse(arg, "ok");
}
static void callback_clean_objectnotify(void *arg, String const &strQuery)
{
- rho_sync_cleanobjectnotify();
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
+ // rho_sync_cleanobjectnotify();
+ rho::sync::RhoconnectClientManager::cleanobjectnotify();
+ }
rho_http_sendresponse(arg, "ok");
}
static void callback_set_notification(void *arg, String const &strQuery)
{
@@ -1066,49 +1430,60 @@
}
static void callback_clear_notification(void *arg, String const &strQuery)
{
int nSrcId = -1;
+
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
- size_t nPos = strQuery.find("srcName=");
- if ( nPos != String::npos )
- {
- String strSrcId = strQuery.substr(nPos+8);
- LOG(INFO) + "srcName = '" + strSrcId + "'";
- nSrcId = atoi(strSrcId.c_str());
- rho_sync_clear_notification(nSrcId);
- } else {
- LOG(WARNING) + "Unable to find 'srcName' parameter";
- }
+ size_t nPos = strQuery.find("srcName=");
+ if ( nPos != String::npos )
+ {
+ String strSrcId = strQuery.substr(nPos+8);
+ LOG(INFO) + "srcName = '" + strSrcId + "'";
+ nSrcId = atoi(strSrcId.c_str());
+ // rho_sync_clear_notification(nSrcId);
+ rho::sync::RhoconnectClientManager::clear_notification(nSrcId);
+ } else {
+ LOG(WARNING) + "Unable to find 'srcName' parameter";
+ }
+
+ }
+
rho_http_sendresponse(arg, "ok");
}
static void callback_login(void *arg, String const &strQuery)
{
int nLevel = 0;
String strLogin, strPassword, strCallback;
+
+ if (rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl()) {
- CTokenizer oTokenizer(strQuery, "&");
- while (oTokenizer.hasMoreTokens())
- {
- String tok = oTokenizer.nextToken();
- if (tok.length() == 0)
- continue;
+ CTokenizer oTokenizer(strQuery, "&");
+ while (oTokenizer.hasMoreTokens())
+ {
+ String tok = oTokenizer.nextToken();
+ if (tok.length() == 0)
+ continue;
- if ( String_startsWith(tok, "login=") )
- {
- strLogin = tok.substr(6);
- }else if ( String_startsWith( tok, "password=") )
- {
- strPassword = tok.substr(9);
- }else if ( String_startsWith( tok, "callback=") )
- {
- strCallback = rho::net::URI::urlDecode(tok.substr(9));
- }
- }
+ if ( String_startsWith(tok, "login=") )
+ {
+ strLogin = tok.substr(6);
+ }else if ( String_startsWith( tok, "password=") )
+ {
+ strPassword = tok.substr(9);
+ }else if ( String_startsWith( tok, "callback=") )
+ {
+ strCallback = rho::net::URI::urlDecode(tok.substr(9));
+ }
+ }
- rho_sync_login(strLogin.c_str(), strPassword.c_str(), strCallback.c_str());
+// rho_sync_login(strLogin.c_str(), strPassword.c_str(), strCallback.c_str());
+ rho::sync::RhoconnectClientManager::login(strLogin.c_str(), strPassword.c_str(), strCallback.c_str());
+ }
+
rho_http_sendresponse(arg, "ok");
}
static void callback_dosearch(void *arg, String const &strQuery)
{
@@ -1126,12 +1501,16 @@
{
//TODO: stub (DmitryP)
rho_http_sendresponse(arg, "ok");
}
+void CRhodesApp::registerLocalServerUrl(const String& strUrl, rho::net::CHttpServer::callback_t const &callback)
+{
+ if ( m_httpServer )
+ m_httpServer->register_uri(strUrl.c_str(), callback);
+}
-
void CRhodesApp::initHttpServer()
{
String strAppRootPath = getRhoRootPath();
String strAppUserPath = getRhoUserPath();
String strRuntimePath = getRhoRuntimePath();
@@ -1143,10 +1522,17 @@
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);
+
+#ifndef RHO_NO_JS_API
+ m_httpServer->register_uri( "/system/js_api_entrypoint", rho::apiGenerator::rho_http_js_entry_point );
+#endif
+
+ m_httpServer->register_uri("/system/call_ruby_proc_callback", rho::net::rho_http_ruby_proc_callback );
+
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);
m_httpServer->register_uri("/system/deactivateapp", callback_deactivateapp);
m_httpServer->register_uri("/system/uicreated", callback_uicreated);
@@ -1182,14 +1568,19 @@
m_httpServer->register_uri("/system/syncengine/clear_notification", callback_clear_notification);
m_httpServer->register_uri("/system/syncengine/login", callback_login);
m_httpServer->register_uri("/system/syncengine/dosearch", callback_dosearch);
m_httpServer->register_uri("/system/syncengine/get_src_attrs", callback_get_src_attrs);
m_httpServer->register_uri("/system/syncengine/is_blob_attr", callback_is_blob_attr);
+
+
}
const char* CRhodesApp::getFreeListeningPort()
{
+ if ( m_isJSFSApp )
+ return "";
+
if ( m_strListeningPorts.length() > 0 )
return m_strListeningPorts.c_str();
int nFreePort = determineFreeListeningPort();
m_strListeningPorts = convertToStringA(nFreePort);
@@ -1212,24 +1603,25 @@
{
LOG(ERROR) + "Unable to open socket";
noerrors = 0;
}
- int disable = 0;
- if (noerrors && setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&disable, sizeof(disable)) != 0)
+ int optval = 1;
+ if (noerrors && setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(optval)) != 0)
{
LOG(ERROR) + "Unable to set socket option";
noerrors = 0;
}
+
#if defined(OS_MACOSX)
- if (noerrors && setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const char *)&disable, sizeof(disable)) != 0)
+ if (noerrors && setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, (const char *)&optval, sizeof(optval)) != 0)
{
LOG(ERROR) + "Unable to set socket option";
noerrors = 0;
}
#endif
-
+
if (noerrors)
{
int listenPort = rho_conf_getInt("local_server_port");
if (listenPort < 0)
listenPort = 0;
@@ -1300,40 +1692,126 @@
closesocket(sockfd);
#endif
return nFreePort;
}
-
+
+#ifdef OS_WINCE
+bool CRhodesApp::isWebkitOutofProcess()
+{
+ const char* szOutprocess = get_app_build_config_item("webkit_outprocess");
+ return szOutprocess && strcmp(szOutprocess, "1") == 0;
+}
+#endif
+
void CRhodesApp::initAppUrls()
{
CRhodesAppBase::initAppUrls();
-
-#if defined( __SYMBIAN32__ ) || defined( OS_ANDROID )
- m_strHomeUrl = "http://localhost:";
-#elif defined( OS_WINCE ) && !defined(OS_PLATFORM_MOTCE)
- TCHAR oem[257];
- SystemParametersInfo(SPI_GETPLATFORMNAME, sizeof(oem), oem, 0);
- LOG(INFO) + "Device name: " + oem;
- //if ((_tcscmp(oem, _T("MC75"))==0) || (_tcscmp(oem, _T("MC75A"))==0))
- // m_strHomeUrl = "http://localhost:";
- //else
- m_strHomeUrl = "http://127.0.0.1:";
-#else
- m_strHomeUrl = "http://127.0.0.1:";
+
+ m_isJSFSApp = false;
+
+#ifdef RHO_NO_RUBY_API
+ m_isJSFSApp = String_startsWith(getStartUrl(), "file:") ? true : false;
#endif
+
+#ifdef OS_WINCE
+ if (isWebkitOutofProcess())
+ m_isJSFSApp = false; //We need local server for out of process webkit, it use sockets to call common API
+#endif
+
+ m_strHomeUrl = "http://127.0.0.1:";
m_strHomeUrl += getFreeListeningPort();
- m_strHomeUrlLocalHost = String("http://localhost:") + getFreeListeningPort();
#ifndef RHODES_EMULATOR
m_strLoadingPagePath = "file://" + getRhoRootPath() + "apps/app/loading.html";
m_strLoadingPngPath = getRhoRootPath() + "apps/app/loading.png";
#else
m_strLoadingPagePath = "file://" + getRhoRootPath() + "app/loading.html";
m_strLoadingPngPath = getRhoRootPath() + "app/loading.png";
#endif
+
+ //write local server url to file
+#ifdef OS_WINCE
+ if (!m_isJSFSApp)
+ {
+ /*String strLSPath = CFilePath::join(m_strRuntimePath.substr(0, m_strRuntimePath.length()-4), "RhoLocalserver.txt"); //remove rho/
+ CRhoFile::writeStringToFile( strLSPath.c_str(), m_strHomeUrl.substr(7, m_strHomeUrl.length()));*/
+ modifyRhoApiFile();
+ }
+#endif
}
+void CRhodesApp::modifyRhoApiFile()
+{
+ const int bufferLenght = 10240;
+
+ std::vector<String> apiFilePathV;
+ apiFilePathV.push_back(m_strRuntimePath);
+ apiFilePathV.push_back("apps");
+ apiFilePathV.push_back("public");
+ apiFilePathV.push_back("api");
+ apiFilePathV.push_back("rhoapi-modules.js");
+
+ String apiFilePath = CFilePath::join(apiFilePathV);
+
+ std::vector<String> apiFilePathTmpV;
+ apiFilePathTmpV.push_back(m_strRuntimePath);
+ apiFilePathTmpV.push_back("apps");
+ apiFilePathTmpV.push_back("public");
+ apiFilePathTmpV.push_back("api");
+ apiFilePathTmpV.push_back("rhoapi-modules-tmp.js");
+
+ String apiFilePathTmp = CFilePath::join(apiFilePathTmpV);
+
+ if (common::CRhoFile::isFileExist(apiFilePath.c_str()))
+ {
+ common::CRhoFile apiFile, tmpFile;
+
+ if (apiFile.open(apiFilePath.c_str(), common::CRhoFile::OpenReadOnly) &&
+ tmpFile.open(apiFilePathTmp.c_str(), common::CRhoFile::OpenForWrite))
+ {
+ common::InputStream* is = apiFile.getInputStream();
+
+ char buffer[bufferLenght];
+ buffer[0] = '\0';
+
+ while (is->available())
+ {
+ int realLen = is->read(buffer, 0, bufferLenght);
+
+ if (realLen == -1)
+ break;
+
+ buffer[realLen] = 0;
+
+ String bufferStr(buffer);
+
+ String::size_type posStart = bufferStr.find("RHO_AJAX");
+ String::size_type posEnd = bufferStr.find("PORT_NUMBER");
+
+ if (posStart != String::npos && posEnd != String::npos)
+ {
+ String::size_type replaceLen = posEnd - posStart + 13;
+
+ String portStr = "\'RHO_AJAX-->";
+ portStr += getFreeListeningPort();
+ portStr += "<--PORT_NUMBER\'";
+ bufferStr.replace(posStart - 1, replaceLen, portStr.c_str());
+ }
+
+ tmpFile.write(bufferStr.c_str(), bufferStr.size());
+ }
+
+ apiFile.close();
+ tmpFile.close();
+
+ common::CRhoFile::deleteFile(apiFilePath.c_str());
+ common::CRhoFile::renameFile(apiFilePathTmp.c_str(), apiFilePath.c_str());
+ }
+ }
+}
+
void CRhodesApp::keepLastVisitedUrl(String strUrl)
{
//LOG(INFO) + "Current URL: " + strUrl;
int nIndex = rho_webview_active_tab();
if (nIndex < 0) nIndex = 0;
@@ -1392,29 +1870,39 @@
}
void CRhodesApp::navigateBack()
{
int nIndex = rho_webview_active_tab();
+ if (nIndex < 0)
+ nIndex = 0;
if((nIndex < static_cast<int>(m_arAppBackUrlOrig.size()))
&& (m_arAppBackUrlOrig[nIndex].length() > 0))
{
- loadUrl(m_arAppBackUrlOrig[nIndex]);
+ String backUrl = m_arAppBackUrlOrig[nIndex];
+ setAppBackUrl("");
+ loadUrl(backUrl);
}
- else if(strcasecmp(getCurrentUrl(nIndex).c_str(),getStartUrl().c_str()) != 0)
+ else// if(strcasecmp(getCurrentUrl(nIndex).c_str(),getStartUrl().c_str()) != 0)
{
- rho_webview_navigate_back();
+ rho_webview_navigate_back_with_tab(nIndex);
}
}
String CRhodesApp::getAppName()
{
String strAppName;
-#ifdef WINDOWS_PLATFORM
+
+#if (defined(OS_WINDOWS_DESKTOP) || defined(OS_WINCE)) && !defined(RHODES_EMULATOR) && !defined(RHODES_QT_PLATFORM)
strAppName = rho_native_get_appname();
+
+#elif(defined(RHODES_EMULATOR))
+ strAppName = RHOSIMCONF().getString("app_name");
+
#else
- strAppName = "Rhodes";
+ //TODO: Android - get app name for shared runtime app
+ strAppName = RHOCONF().getString("app_name");
#endif
return strAppName;
}
@@ -1458,11 +1946,10 @@
{
return strncmp(strCurUrl.c_str(), strStart.c_str(), strCurUrl.length() - nIndexLen - 1) == 0;
}
return false;
-
}
const String& CRhodesApp::getBaseUrl()
{
return m_strHomeUrl;
@@ -1490,44 +1977,54 @@
rho_webview_navigate(strUrl.c_str(), -1);
}
String CRhodesApp::addCallbackObject(ICallbackObject* pCallbackObject, String strName)
{
- int nIndex = -1;
- for (int i = 0; i < (int)m_arCallbackObjects.size(); i++)
+ synchronized(m_mxCallbackObjects)
{
- if ( m_arCallbackObjects.elementAt(i) == 0 )
- nIndex = i;
- }
- if ( nIndex == -1 )
- {
- m_arCallbackObjects.addElement(pCallbackObject);
- nIndex = m_arCallbackObjects.size()-1;
- }else
- m_arCallbackObjects.setElementAt(pCallbackObject,nIndex);
+ int nIndex = -1;
+ for (int i = 0; i < (int)m_arCallbackObjects.size(); i++)
+ {
+ if ( m_arCallbackObjects.elementAt(i) == 0 )
+ nIndex = i;
+ }
+ if ( nIndex == -1 )
+ {
+ m_arCallbackObjects.addElement(pCallbackObject);
+ nIndex = m_arCallbackObjects.size()-1;
+ }else
+ m_arCallbackObjects.setElementAt(pCallbackObject,nIndex);
- String strRes = "__rho_object[" + strName + "]=" + convertToStringA(nIndex);
+ String strRes = "__rho_object[" + strName + "]=" + convertToStringA(nIndex);
- return strRes;
+ return strRes;
+ }
}
unsigned long CRhodesApp::getCallbackObject(int nIndex)
{
- if ( nIndex < 0 || nIndex > (int)m_arCallbackObjects.size() )
- return rho_ruby_get_NIL();
+#ifndef RHO_NO_RUBY_API
+ synchronized(m_mxCallbackObjects)
+ {
+ if ( nIndex < 0 || nIndex > (int)m_arCallbackObjects.size() )
+ return rho_ruby_get_NIL();
- ICallbackObject* pCallbackObject = m_arCallbackObjects.elementAt(nIndex);
- m_arCallbackObjects.setElementAt(0,nIndex);
+ ICallbackObject* pCallbackObject = m_arCallbackObjects.elementAt(nIndex);
+ m_arCallbackObjects.setElementAt(0,nIndex);
- if ( !pCallbackObject )
- return rho_ruby_get_NIL();
+ if ( !pCallbackObject )
+ return rho_ruby_get_NIL();
- unsigned long valRes = pCallbackObject->getObjectValue();
+ unsigned long valRes = pCallbackObject->getObjectValue();
- delete pCallbackObject;
+ delete pCallbackObject;
- return valRes;
+ return valRes;
+ }
+#else
+ return 6; //Ruby Qundef
+#endif
}
void CRhodesApp::initPushClients()
{
static bool first = true;
@@ -1538,72 +2035,55 @@
}
}
void CRhodesApp::setPushNotification(const String& strUrl, const String& strParams, const String& strType )
{
- if(strType == "legacy")
+ if(strType == "legacy" || strType == "default")
{
+ LOG(TRACE) + "Set notification for legacy push: " + strUrl;
synchronized(m_mxPushCallback)
{
m_strPushCallback = strUrl;
if (m_strPushCallback.length())
m_strPushCallback = canonicalizeRhoUrl(m_strPushCallback);
m_strPushCallbackParams = strParams;
}
}
- else
+
+ if(strType != "legacy")
{
+ LOG(TRACE) + "Set Push Manager notification for " + strType + " push: " + strUrl;
+
String canonicalUrl;
if (strUrl.length())
canonicalUrl = canonicalizeRhoUrl(strUrl);
- if(strType.length())
+ if(strType != "default")
m_appPushMgr.setNotificationUrl(strType, canonicalUrl, strParams);
else
m_appPushMgr.setNotificationUrl(canonicalUrl, strParams);
}
}
-// Deprecated
-boolean CRhodesApp::callPushCallback(const String& strData) const
-{
- synchronized(m_mxPushCallback)
- {
- if ( m_strPushCallback.length() == 0 )
- return false;
- String strBody = strData + "&rho_callback=1";
- if ( m_strPushCallbackParams.length() > 0 )
- strBody += "&" + m_strPushCallbackParams;
-
- NetResponse resp = getNetRequest().pushData( m_strPushCallback, strBody, null );
- if (!resp.isOK())
- LOG(ERROR) + "Push notification failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
- else
- {
- const char* szData = resp.getCharData();
- return !(szData && strcmp(szData,"rho_push") == 0);
- }
- }
-
- return false;
-}
-
-boolean CRhodesApp::callPushCallbackWithJsonBody(const String& strUrl, const String& strData, const String& strParams)
+boolean CRhodesApp::callPushCallbackWithJsonBody(const String& strUrl, const String& strJson, const String& strParams)
{
synchronized(m_mxPushCallback)
{
if (strUrl.length() == 0)
return false;
String strCanonicalUrl = canonicalizeRhoUrl(strUrl);
- String strBody = addCallbackObject( new CJsonResponse( strData ), "__rho_inline" ) + "&rho_callback=1";
+ String strBody = strJson.length() ? (addCallbackObject( new CJsonResponse( strJson ), "__rho_inline" ) + "&rho_callback=1") : strJson;
if (strParams.length() > 0)
{
- strBody += "&";
+ if (strBody.length())
+ {
+ strBody += "&";
+ }
strBody += strParams;
}
NetResponse resp = getNetRequest().pushData( strCanonicalUrl, strBody, null );
if (!resp.isOK())
@@ -1667,129 +2147,198 @@
LOG(ERROR) + "Screen rotation notification failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
}
}
}
-void CRhodesApp::loadUrl(String url)
+void CRhodesApp::callScreenOnCallbackAsync()
{
+ m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::screen_on));
+}
+
+void CRhodesApp::loadUrl(String url, int nTabIndex/* = -1*/)
+{
if ( url.length() == 0 )
return;
- boolean callback = false;
+ boolean callback = false, js_callback = false;
if (String_startsWith(url, "callback:") )
{
callback = true;
url = url.substr(9);
+ }else if (String_startsWith(url, "javascript:") )
+ {
+ js_callback = true;
+ url = url.substr(11);
+ }else if (String_startsWith(url, "__rhoCallback:") )
+ {
+ js_callback = true;
+ url = url.substr(14);
+
+ String strCallback("Rho.callbackHandler( \"");
+ strCallback += url;
+ strCallback += "\", {},\"\")";
+
+ url = strCallback;
}else if ( strcasecmp(url.c_str(), "exit")==0 || strcasecmp(url.c_str(), "close") == 0 )
{
rho_sys_app_exit();
return;
}else if ( strcasecmp(url.c_str(), "options")==0 )
{
- rho_webview_navigate(getOptionsUrl().c_str(), 0);
+ rho_webview_navigate(getOptionsUrl().c_str(), -1);
return;
}else if ( strcasecmp(url.c_str(), "home")==0 )
{
- rho_webview_navigate(getStartUrl().c_str(), 0);
+ rho_webview_navigate(getStartUrl().c_str(), -1);
return;
}else if ( strcasecmp(url.c_str(), "refresh")==0 )
{
- rho_webview_refresh(0);
+ rho_webview_refresh(nTabIndex);
return;
}else if ( strcasecmp(url.c_str(), "back")==0 )
{
navigateBack();
return;
+ }else if ( strcasecmp(url.c_str(), "log")==0 )
+ {
+ rho_conf_show_log();
+ return;
+ }else if ( strcasecmp(url.c_str(), "fullscreen")==0 )
+ {
+ rho_webview_full_screen_mode(1);
+ return;
}else if ( strcasecmp(url.c_str(), "sync")==0 )
{
- rho_sync_doSyncAllSources(1,"",false);
+ if ( rho::sync::RhoconnectClientManager::haveRhoconnectClientImpl() ) {
+ rho::sync::RhoconnectClientManager::doSyncAllSources(1,"",false);
+
+ }
+
return;
+ }else if ( strcasecmp(url.c_str(), "minimize")==0 )
+ {
+ getExtManager().minimizeApp();
+ return;
+ }else if ( strcasecmp(url.c_str(), "SIP")==0 )
+ {
+#ifdef OS_WINCE
+ RHODESAPP().getExtManager().OnSIPState(true);
+#endif
+ return;
}
- url = canonicalizeRhoUrl(url);
if (callback)
{
+ url = canonicalizeRhoUrl(url);
if ( rho_ruby_is_started() )
getNetRequest().pushData( url, "rho_callback=1", null );
}
+ else if (js_callback)
+ rho_webview_execute_js(url.c_str(), nTabIndex);
else
- navigateToUrl(url);
+ {
+ url = canonicalizeRhoUrl(url);
+ rho_webview_navigate(url.c_str(), nTabIndex);
+ }
}
void CRhodesApp::notifyLocalServerStarted()
{
m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::local_server_started));
}
+extern "C" int rho_ruby_is_started();
+extern "C" unsigned long rho_ruby_safe_require(const char *fname);
+
+void CExtManager::requireRubyFile( const char* szFilePath )
+{
+#ifndef RHO_NO_RUBY_API
+ if( rho_ruby_is_started() )
+ {
+ RAWTRACEC1("CExtManager", "Require ruby file: %s", szFilePath);
+ unsigned long val = rho_ruby_safe_require(szFilePath);
+ if ( rho_ruby_is_NIL(val) )
+ RAWLOGC_WARNING1("CExtManager", "requireRubyFile cannot find file: %s", szFilePath);
+ }
+#endif
+}
- void CRhodesApp::setNetworkStatusNotify(const String& url, int poll_interval)
+void CRhodesApp::setNetworkStatusNotify(const apiGenerator::CMethodResult& oResult, int poll_interval)
+{
+ synchronized(m_mxNetworkStatus)
{
- synchronized(m_mxNetworkStatus)
+ m_networkStatusReceiver.setMethodResult(oResult);
+ if ( m_pNetworkStatusMonitor != 0 )
{
- String s = url;
- if (s.length() > 0) {
- s = canonicalizeRhoUrl(url);
+ if ( poll_interval <= 0 ) {
+ poll_interval = c_defaultNetworkStatusPollInterval;
}
- m_networkStatusReceiver.setCallbackUrl(s);
- if ( m_pNetworkStatusMonitor != 0 )
- {
- if ( poll_interval <= 0 ) {
- poll_interval = c_defaultNetworkStatusPollInterval;
- }
- m_pNetworkStatusMonitor->setPollInterval(poll_interval);
- }
+ m_pNetworkStatusMonitor->setPollInterval(poll_interval);
}
}
-
- void CRhodesApp::clearNetworkStatusNotify()
+}
+
+void CRhodesApp::clearNetworkStatusNotify()
+{
+ synchronized(m_mxNetworkStatus)
{
- synchronized(m_mxNetworkStatus)
- {
- m_networkStatusReceiver.setCallbackUrl("");
- }
+ m_networkStatusReceiver.setMethodResult(apiGenerator::CMethodResult());
}
-
- void CRhodesApp::setNetworkStatusMonitor( INetworkStatusMonitor* netMonitor )
+}
+
+void CRhodesApp::setNetworkStatusMonitor( INetworkStatusMonitor* netMonitor )
+{
+ synchronized(m_mxNetworkStatus)
{
- synchronized(m_mxNetworkStatus)
+ m_pNetworkStatusMonitor = netMonitor;
+ if ( m_pNetworkStatusMonitor != 0)
{
- m_pNetworkStatusMonitor = netMonitor;
- if ( m_pNetworkStatusMonitor != 0)
- {
- m_pNetworkStatusMonitor->setNetworkStatusReceiver(&m_networkStatusReceiver);
- m_pNetworkStatusMonitor->setPollInterval( c_defaultNetworkStatusPollInterval );
- }
+ m_pNetworkStatusMonitor->setNetworkStatusReceiver(&m_networkStatusReceiver);
+ m_pNetworkStatusMonitor->setPollInterval( c_defaultNetworkStatusPollInterval );
}
}
+}
NetworkStatusReceiver::NetworkStatusReceiver( common::CMutex& mxAccess ) :
m_prevStatus( networkStatusUnknown ),
m_mxAccess(mxAccess)
{
}
+
+ void CRhodesApp::setApplicationEventHandler(apiGenerator::CMethodResult& oResult)
+ {
+ m_applicationEventReceiver.setCallback(oResult);
+ }
+
+ void CRhodesApp::clearApplicationEventHandler()
+ {
+ apiGenerator::CMethodResult tmp;
+ m_applicationEventReceiver.setCallback(tmp);
+ }
+
+ IApplicationEventReceiver* CRhodesApp::getApplicationEventReceiver()
+ {
+ return &m_applicationEventReceiver;
+ }
void NetworkStatusReceiver::onNetworkStatusChanged( enNetworkStatus currentStatus )
{
- if ( !rho_ruby_is_started() )
- return;
-
synchronized(m_mxAccess)
{
- if ( !m_callbackUrl.empty() && (m_prevStatus != currentStatus) )
+ if ( m_prevStatus != currentStatus )
{
- String strBody = "";
- strBody += "current_status=" + networkStatusToString(currentStatus);
- strBody += "&prev_status=" + networkStatusToString(m_prevStatus);
-
- NetResponse resp = getNetRequest().pushData( m_callbackUrl, strBody, null );
-
- if ( !resp.isOK() )
- {
- LOG(ERROR) + "Fire notification failed. Code: " + resp.getRespCode() + "; Error body: " + resp.getCharData();
- }
+ String sCurrentStatus = networkStatusToString(currentStatus);
+ String sPrevStatus = networkStatusToString(m_prevStatus);
+
+ Hashtable<String, String> ret;
+
+ ret.put("current_status", sCurrentStatus);
+ ret.put("prev_status", sPrevStatus);
+
+ m_result.set(ret);
}
m_prevStatus = currentStatus;
}
}
@@ -1807,11 +2356,174 @@
return "unknown";
break;
}
return "";
}
+
+ ApplicationEventReceiver::ApplicationEventReceiver() :
+ m_app_state(applicationStateUninitialized),
+ m_ui_state(UIStateUninitialized)
+ {
+
+ }
+
+ bool ApplicationEventReceiver::onAppStateChange(const enApplicationState& newState)
+ {
+ if (m_app_state != newState)
+ {
+ m_app_state = newState;
+ if (m_result.hasCallback())
+ {
+ rho::Hashtable<rho::String, rho::String> callbackData;
+ const char* state = APP_EVENT_UNINITIALIZED;
+ switch (newState) {
+ case applicationStateActivated:
+ state = APP_EVENT_ACTIVATED;
+ break;
+ case applicationStateDeactivated:
+ // special case, should be processed in foreground
+ m_result.setSynchronousCallback(true);
+ state = APP_EVENT_DEACTIVATED;
+ break;
+ default:
+ state = APP_EVENT_UNINITIALIZED;
+ break;
+ }
+ callbackData.put(APP_EVENT, state);
+
+ m_result.set(callbackData);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ApplicationEventReceiver::onUIStateChange(const enUIState& newState)
+ {
+ // UIDestroyed is called when app is terminating or going to background mode
+ // UICreated is called only when app is created
+ // Events should be sent in any case
+ if (m_ui_state != newState)
+ {
+ m_ui_state = newState;
+ if (m_result.hasCallback())
+ {
+ rho::Hashtable<rho::String, rho::String> callbackData;
+ const char* state = APP_EVENT_UNINITIALIZED;
+ switch (newState) {
+ case UIStateCreated:
+ m_result.setSynchronousCallback(true);
+ state = APP_EVENT_UICREATED;
+ break;
+ case UIStateDestroyed:
+ m_result.setSynchronousCallback(true);
+ state = APP_EVENT_UIDESTROYED;
+ break;
+ default:
+ state = APP_EVENT_UNINITIALIZED;
+ break;
+ }
+ callbackData.put(APP_EVENT, state);
+ m_result.set(callbackData);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool ApplicationEventReceiver::onSyncUserChanged()
+ {
+ if (!m_result.hasCallback())
+ return false;
+ rho::Hashtable<rho::String, rho::String> callbackData;
+
+ callbackData.put(APP_EVENT, APP_EVENT_SYNCUSERCHANGED);
+ m_result.set(callbackData);
+
+ return true;
+ }
+
+ bool ApplicationEventReceiver::onReinstallConfigUpdate(const HashtablePtr<String,Vector<String>* >& conflicts)
+ {
+ // at this point http server is not yet started
+ // there is no way to call ruby and javascript callbacks
+ // TODO: find a way to execute ruby callbacks during initialization
+ if (!RHODESAPP().isLocalServerRunning())
+ {
+ return false;
+ }
+
+ using namespace rho::apiGenerator;
+ if (m_result.hasCallback() && (conflicts.size() > 0) )
+ {
+ StringifyHash confhash;
+ for ( HashtablePtr<String,Vector<String>* >::const_iterator it=conflicts.begin() ; it != conflicts.end(); it++ )
+ {
+ String key = it->first;
+ Vector<String>& ref = *(it->second);
+ StringifyVector vect;
+ //Vector<String>& current = conv[key];
+ for( Vector<String>::const_iterator it2=ref.begin(); it2 != ref.end(); it2++)
+ {
+ vect.push_back(*it2);
+ }
+ confhash.set(key, vect);
+ }
+
+ StringifyHash result;
+ result.set(APP_EVENT, APP_EVENT_CONFIGCONFLICT);
+ result.set(APP_EVENT_DATA, confhash);
+
+ rho::String buffer;
+ result.toString(buffer);
+
+ m_result.setJSON(buffer);
+ }
+
+ return false;
+ }
+
+ bool ApplicationEventReceiver::onMigrateSource(){
+ return false;
+ }
+
+ bool ApplicationEventReceiver::onDeviceScreenEvent(const int newState) {
+ if (m_result.hasCallback())
+ {
+ rho::Hashtable<rho::String, rho::String> callbackData;
+ const char* state = APP_EVENT_UNINITIALIZED;
+ m_result.setSynchronousCallback(false);
+ switch (newState) {
+ case screenOff:
+ state = APP_EVENT_SCREEN_OFF;
+ //special case: need to call screenOff callback synchronously to make it called before device goes to inactive state.
+ m_result.setSynchronousCallback(true);
+ break;
+ case screenOn:
+ state = APP_EVENT_SCREEN_ON;
+ break;
+ default:
+ state = APP_EVENT_UNINITIALIZED;
+ break;
+ }
+ callbackData.put(APP_EVENT, state);
+ m_result.set(callbackData);
+ return true;
+ }
+
+ return true;
+ }
+
+ bool ApplicationEventReceiver::isCallbackSet(){
+ return m_result.hasCallback();
+ }
+
+ void ApplicationEventReceiver::setCallback(apiGenerator::CMethodResult& oResult){
+ m_result = oResult;
+ }
+
} //namespace common
} //namespace rho
@@ -1905,10 +2617,91 @@
n = buflen - 1;
buf[n] = '\0';
return (n);
}
+
+int rho_http_started()
+{
+ return RHODESAPP().isLocalServerRunning()?1:0;
+}
+
+int rho_http_get_port()
+{
+ return RHODESAPP().getLocalServerPort();
+}
+
+#ifdef OS_MACOSX
+const char* rho_http_direct_request( const char* method, const char* uri, const char* query, const void* headers, const char* body, int* responseLength )
+{
+
+ String sMethod;
+ String sUri;
+ String sQuery;
+ String sBody;
+ rho::net::HttpHeaderList oHeaders;
+
+ if ( method != 0 ) {
+ sMethod = method;
+ }
+
+ if ( uri != 0 ) {
+ sUri = uri;
+ }
+
+ if ( query != 0 ) {
+ sQuery = query;
+ }
+
+ if ( body != 0 ) {
+ sBody = body;
+ }
+
+ if ( headers != 0 ) {
+ oHeaders = *(rho::net::HttpHeaderList*)headers;
+ }
+
+ String response = RHODESAPP().directHttpRequest( sMethod, sUri, sQuery, oHeaders, sBody );
+
+ char* ret = 0;
+
+ if ( response.length() != 0 ) {
+ ret = new char[response.length() + 1];
+ memmove(ret, response.c_str(), response.length());
+ }
+
+ if ( responseLength != 0 )
+ {
+ *responseLength = (int)response.length();
+ }
+
+ return ret;
+}
+
+void rho_http_free_response( const char* data )
+{
+ delete[] data;
+}
+
+void* rho_http_init_headers_list()
+{
+ return new rho::net::HttpHeaderList();
+}
+
+void rho_http_add_header( void* list, const char* name, const char* value )
+{
+ if ( ( name != 0 ) && ( value != 0 ) ) {
+ ((rho::net::HttpHeaderList*)list)->addElement( rho::net::HttpHeader(name,value));
+ }
+}
+
+void rho_http_free_headers_list( void* list )
+{
+ delete (rho::net::HttpHeaderList*)list;
+}
+#endif
+
void rho_rhodesapp_create(const char* szRootPath)
{
rho::common::CRhodesApp::Create(szRootPath, szRootPath, szRootPath);
}
@@ -1983,15 +2776,15 @@
const char* rho_rhodesapp_getdbdirpath()
{
return RHODESAPP().getDBDirPath().c_str();
}
-const char* rho_rhodesapp_getapprootpath() {
+const char* rho_rhodesapp_getapprootpath()
+{
return RHODESAPP().getAppRootPath().c_str();
}
-
void rho_rhodesapp_navigate_back()
{
RHODESAPP().navigateBack();
}
@@ -2027,36 +2820,53 @@
RHODESAPP().callAppActiveCallback(nActive!=0);
}
void rho_rhodesapp_callUiCreatedCallback()
{
- if ( rho::common::CRhodesApp::getInstance() )
+ if ( rho::common::CRhodesApp::getInstance() )
RHODESAPP().callUiCreatedCallback();
+ else
+ {
+ RAWLOGC_ERROR("RhodesApp", "UI created callback is missing because application instance is NULL");
+ }
}
void rho_rhodesapp_callUiDestroyedCallback()
{
if ( rho::common::CRhodesApp::getInstance() )
RHODESAPP().callUiDestroyedCallback();
}
-void rho_rhodesapp_setViewMenu(unsigned long valMenu)
+void rho_rhodesapp_callScreenOffCallback()
{
- RHODESAPP().getAppMenu().setAppMenu(valMenu);
+ if ( rho::common::CRhodesApp::getInstance() && RHODESAPP().getApplicationEventReceiver() )
+ RHODESAPP().getApplicationEventReceiver()->onDeviceScreenEvent(rho::common::screenOff);
}
+void rho_rhodesapp_callScreenOnCallback()
+{
+ if ( rho::common::CRhodesApp::getInstance() && RHODESAPP().getApplicationEventReceiver() )
+ RHODESAPP().getApplicationEventReceiver()->onDeviceScreenEvent(rho::common::screenOn);
+}
+
+void rho_rhodesapp_callScreenOnCallbackAsync()
+{
+ RHODESAPP().callScreenOnCallbackAsync();
+}
+
+
const char* rho_rhodesapp_getappbackurl()
{
return RHODESAPP().getAppBackUrl().c_str();
}
int rho_rhodesapp_callPushCallback(const char* szData)
{
if ( !rho::common::CRhodesApp::getInstance() )
return 1;
- return RHODESAPP().callPushCallback(szData?szData:"") ? 1 : 0;
+ return RHODESAPPBASE().callPushCallback(szData?szData:"") ? 1 : 0;
}
//int rho_rhodesapp_callPushCallbackWithJsonBody(const char* szUrl, const char* szData, const char* szParam)
//{
// if ( !rho::common::CRhodesApp::getInstance() )
@@ -2092,16 +2902,10 @@
{
String strCallbackUrl = RHODESAPP().canonicalizeRhoUrl(url);
getNetRequest().pullData(strCallbackUrl.c_str(), null);
}
-void rho_net_request_with_data(const char *url, const char *str_body)
-{
- String strCallbackUrl = RHODESAPP().canonicalizeRhoUrl(url);
- getNetRequest().pushData(strCallbackUrl.c_str(), str_body, null);
-}
-
void rho_net_request_with_data_in_separated_thread(const char *url, const char *str_body) {
String strCallbackUrl = RHODESAPP().canonicalizeRhoUrl(url);
String strBody = str_body;
RHODESAPP().runCallbackInThread(strCallbackUrl, strBody);
}
@@ -2144,10 +2948,24 @@
void rho_free_callbackdata(void* pData)
{
//It is used in SyncClient.
}
+const char* rho_rhodesapp_getStartParametersOriginal()
+{
+ return RHODESAPP().getStartParametersOriginal().c_str();
+}
+
+void rho_rhodesapp_setStartParametersOriginal(const char* szParams)
+{
+ RHODESAPP().setStartParametersOriginal(szParams? szParams:"");
+}
+
+int rho_rhodesapp_is_application_active() {
+ return RHODESAPP().isApplicationActive() ? 1 : 0;
+}
+
int rho_rhodesapp_canstartapp(const char* szCmdLine, const char* szSeparators)
{
String strCmdLineSecToken;
String security_key = "security_token=";
String strCmdLine = szCmdLine ? szCmdLine : "";
@@ -2176,56 +2994,43 @@
CRhodesApp::setSecurityTokenNotPassed(!result);
return result;
}
-int rho_is_motorola_licence_checked(const char* szMotorolaLicence, const char* szMotorolaLicenceCompany, const char* szAppName)
-{
- int res_check = 1;
-#if defined( OS_ANDROID ) || defined( OS_MACOSX )
- //res_check = MotorolaLicence_check(szMotorolaLicenceCompany, szMotorolaLicence);
- res_check = MotorolaLicence_check(szMotorolaLicenceCompany, szMotorolaLicence, szAppName);
-#endif
-
- return res_check;
-}
-
-int rho_is_rho_elements_extension_can_be_used(const char* szMotorolaLicence)
-{
- int res_check = 1;
-#if defined( OS_MACOSX ) || defined( OS_ANDROID )
- if (szMotorolaLicence == NULL)
- {
- res_check = 0;
- }
-#endif
-
- return res_check;
-}
-
-int rho_can_app_started_with_current_licence(const char* szMotorolaLicence, const char* szMotorolaLicenceCompany, const char* szAppName)
-{
- if (szMotorolaLicence == NULL)
- {
- return 1;
- }
-
- int res_check = 1;
-#if defined( OS_MACOSX ) || defined( OS_ANDROID )
- res_check = rho_is_motorola_licence_checked(szMotorolaLicence, szMotorolaLicenceCompany, szAppName);
-#endif
- return res_check;
-}
-
- void rho_sys_set_network_status_notify(const char* url, int poll_interval)
+ //TODO: remove it
+ void rho_sys_set_network_status_notify(const char* /*url*/, int /*poll_interval*/)
{
- RHODESAPP().setNetworkStatusNotify(url,poll_interval);
+ // commented out because first parameter should be a MethodResult, not char*; so this call will result in 100% app crash
+ //RHODESAPP().setNetworkStatusNotify(url,poll_interval);
}
void rho_sys_clear_network_status_notify()
{
RHODESAPP().clearNetworkStatusNotify();
}
} //extern "C"
+
+#if !defined(OS_WINDOWS_DESKTOP) && !defined(RHODES_EMULATOR) && !defined(OS_ANDROID)
+
+extern "C" void alert_show_status(const char* title, const char* message, const char* szHide);
+
+extern "C"
+{
+ void rho_alert_show_status(char* szTitle, char* szText, char* szHideLabel)
+ {
+ alert_show_status( szTitle ? szTitle : "", szText ? szText : "", szHideLabel ? szHideLabel : "");
+ }
+}
+#endif
+
+extern "C" int rho_is_remote_debug()
+{
+ return RHOCONF().getBool("remotedebug");
+}
+
+extern "C" const char* rho_get_remote_debug_host()
+{
+ return RHOCONF().getString("debughosturl").c_str();
+}