// Poll and notify main thread if responses exists in queue void NetClient::dispatchResponseCallbacks(float delta) { //// log("CCHttpClient::dispatchResponseCallbacks is running"); NetResponse* response = NULL; this->responseqMtx.lock(); if (!this->responseq.empty()) { response = *(this->responseq.begin()); this->responseq.pop_front(); } this->responseqMtx.unlock(); if (response) { --asyncRequestCount; dynamic_cast<NetResponse*>(response)->invoke(); response->release(); } if (0 == asyncRequestCount) { CCDirector::sharedDirector()->getScheduler()->pauseTarget(this); } }
boolean CRhodesApp::sendLog() { 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); if ( !resp.isOK() ) { LOG(ERROR) + "send_log failed : network error - " + resp.getRespCode() + "; Body - " + resp.getCharData(); return false; } return true; }
boolean CClientRegister::doUnregister(CSyncEngine& oSync) { String session = m_unregisterSession; if ( session.length() == 0 ) { m_unregisterSession = ""; m_unregisterClientID = ""; LOG(INFO)+"Session is empty, don't need to unregister"; return true; } m_nPollInterval = POLL_INTERVAL_SECONDS; String client_id = m_unregisterClientID; if ( client_id.length() == 0 ) { m_unregisterSession = ""; m_unregisterClientID = ""; LOG(WARNING)+"Sync client_id is empty, don't need to unregister"; return true; } String strBody = getUnregisterBody(client_id); LOG(INFO)+"Unregistered client with body = " + strBody; class UnregisterSession : public net::IRhoSession { String m_session; String m_contentType; public: UnregisterSession(const String& session, const String& contentType) : m_session(session), m_contentType(contentType) {} virtual void logout() {} virtual const String& getSession() { return m_session; } virtual const String& getContentType() { return m_contentType; } }; UnregisterSession unregSession(session, oSync.getProtocol().getContentType() ); NetResponse resp = getNet().pushData( oSync.getProtocol().getClientRegisterUrl(client_id), strBody, &unregSession ); if( resp.isOK() ) { m_unregisterSession = ""; m_unregisterClientID = ""; CDBAdapter::getUserDB().executeSQL("UPDATE client_info SET token_sent=?", 0 ); LOG(INFO)+"Unregistered client sucessfully..."; return true; } LOG(WARNING)+"Network error: "+ resp.getRespCode(); return false; }
void CRhodesApp::callUiDestroyedCallback() { 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 rho_do_send_log(rho::apiGenerator::CMethodResult& oResult) { String strDevicePin, strClientID; net::IRhoSession* pSession = 0; if ( sync::RhoconnectClientManager::haveRhoconnectClientImpl() ) { strDevicePin = rho::sync::RhoconnectClientManager::clientRegisterGetDevicePin(); strClientID = rho::sync::RhoconnectClientManager::syncEnineReadClientID(); pSession = rho::sync::RhoconnectClientManager::getRhoSession(); } String strQuery; String strLogUrl = RHOCONF().getString("Log.destinationURI"); if ( strLogUrl.length() == 0 ) { strLogUrl = RHOCONF().getPath("logserver"); if ( strLogUrl.length() == 0 ) strLogUrl = RHOCONF().getPath("syncserver"); strQuery = strLogUrl + "client_log?" + "client_id=" + strClientID + "&device_pin=" + strDevicePin + "&log_name=" + RHOCONF().getString("logname"); }else { String strSign = "?"; if ( strrchr(strLogUrl.c_str(), '?') ) strSign = "&"; strQuery = strLogUrl + strSign + "client_id=" + strClientID + "&device_pin=" + strDevicePin; } 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, pSession, null ); LOGCONF().setLogToFile(bOldSaveToFile); boolean isOK = true; if ( !resp.isOK() ) { LOG(ERROR) + "send_log failed : network error - " + resp.getRespCode() + "; Body - " + resp.getCharData(); isOK = false; } Hashtable<String, String> hashRes; hashRes["status"] = isOK ? "ok" : "error"; oResult.set(hashRes); RHODESAPPBASE().setSendingLog(false); }
boolean CClientRegister::doRegister(CSyncEngine& oSync) { String session = oSync.loadSession(); if ( session.length() == 0 ) { m_nPollInterval = POLL_INTERVAL_INFINITE; LOG(INFO)+"Session is empty, do register later"; return false; } if ( m_strDevicePin.length() == 0 ) { notifyLoggedIn("","",session); m_nPollInterval = POLL_INTERVAL_INFINITE; LOG(INFO)+"Device PUSH pin is empty, do register later"; return false; } m_nPollInterval = POLL_INTERVAL_SECONDS; String client_id = oSync.loadClientID(); if ( client_id.length() == 0 ) { LOG(WARNING)+"Sync client_id is empty, do register later"; return false; } IDBResult res = CDBAdapter::getUserDB().executeSQL("SELECT token,token_sent from client_info"); if ( !res.isEnd() ) { String token = res.getStringByIdx(0); int token_sent = res.getIntByIdx(1) && !RHOCONF().getBool("register_push_at_startup"); if ( m_strDevicePin.compare(token) == 0 && token_sent > 0 ) { //token in db same as new one and it was already send to the server //so we do nothing return true; } } String strBody = getRegisterBody(client_id); NetResponse resp = getNet().pushData( oSync.getProtocol().getClientRegisterUrl(client_id), strBody, &oSync ); if( resp.isOK() ) { CDBAdapter::getUserDB().executeSQL("UPDATE client_info SET token_sent=?, token=?", 1, m_strDevicePin ); LOG(INFO)+"Registered client sucessfully..."; return true; } LOG(WARNING)+"Network error: "+ resp.getRespCode(); return false; }
bool GoogleGeoCoding::fetchData(String const &url, void **data, size_t *datasize) { RHO_MAP_TRACE1("GoogleGeoCoding: fetchData: url=%s", url.c_str()); NetResponse resp = getNet().doRequest("GET", url, "", 0, 0); if (!resp.isOK()) return false; *datasize = resp.getDataSize(); *data = malloc(*datasize); if (!*data) return false; memcpy(*data, resp.getCharData(), *datasize); return true; }
/*static*/ int _CRhoAppAdapter::getErrorFromResponse(NetResponse& resp) { if ( !resp.isResponseRecieved()) return ERR_NETWORK; if ( resp.isUnathorized() ) return ERR_UNATHORIZED; if ( !resp.isOK() ) return ERR_REMOTESERVER; return ERR_NONE; }
void CRhodesApp::callAppActiveCallback(boolean bActive) { LOG(INFO) + "callAppActiveCallback"; if (bActive) { // Restart server each time when we go to foreground /* if (m_activateCounter++ > 0) { #if !defined( OS_WINCE ) && !defined (OS_WINDOWS) m_httpServer->stop(); #endif this->stopWait(); } */ m_appCallbacksQueue->addQueueCommand(new CAppCallbacksQueue::Command(CAppCallbacksQueue::app_activated)); } else { // Deactivation callback must be called in place (not in separate thread!) // This is because system can kill application at any time after this callback finished // So to guarantee user code is executed on deactivation, we must not exit from this function // until application finish executing of user-defined deactivation callback. // 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)); String strUrl = m_strHomeUrl + "/system/deactivateapp"; NetResponse resp = getNetRequest().pullData( strUrl, null ); if ( !resp.isOK() ) { 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( OS_WINCE ) && !defined (OS_WINDOWS) LOG(INFO) + "Stopping local server."; m_httpServer->stop(); #endif } } m_bDeactivationMode = false; } }
void EventSource::didReceiveResponse(NetResponse& response, const Hashtable<String,String>* headers) { LOG(TRACE) + "didReceiveResponse"; ASSERT(m_state==CONNECTING); int statusCode = response.getRespCode(); bool mimeTypeIsValid = headers->get("content-type") == "text/event-stream"; bool responseIsValid = statusCode == 200 && mimeTypeIsValid; if (responseIsValid) { const String& charset = headers->get("content-encoding"); // If we have a charset, the only allowed value is UTF-8 (case-insensitive). responseIsValid = charset.empty() || (strcasecmp(charset.c_str(), "UTF-8")==0); if (!responseIsValid) { LOG(ERROR) + "EventSource's response has a charset (\"" + charset + "\") that is not UTF-8. Aborting the connection."; } } else { // To keep the signal-to-noise ratio low, we only log 200-response with an invalid MIME type. if (statusCode == 200 && !mimeTypeIsValid) { LOG(ERROR) + "EventSource's response has a MIME type (\"" + headers->get("content-type") + "\") that is not \"text/event-stream\". Aborting the connection."; } } if (responseIsValid) { m_state = OPEN; m_pReceiver->onOpen(); } else { close(); m_pReceiver->onError(""); } }
// Play an audio file. virtual void start( const rho::String& filename, rho::apiGenerator::CMethodResult& oResult) { // Check that the filename is not empty or NULL. if (!filename.empty() && (!m_hPlayThread)) { // Download the audio file and store name in lFilename if(String_startsWith(filename, "http://") || String_startsWith(filename, "https://")) { rho::common::CRhoFile::deleteFile("download.wav"); // Networked code LOG(INFO) + __FUNCTION__ + "Attempting to download the file. " + filename; NetRequest oNetRequest; Hashtable<String,String> mapHeaders; bool overwriteFile = true; bool createFolders = false; bool fileExists = false; String& newfilename = String("download.wav"); // Call the download function with the url and new filename the temp filename to be used. net::CNetRequestHolder *requestHolder = new net::CNetRequestHolder(); requestHolder->setSslVerifyPeer(false); NetResponse resp = getNetRequest(requestHolder).pullFile( filename, newfilename, NULL, &mapHeaders,overwriteFile,createFolders,&fileExists); delete requestHolder; if (!resp.isOK()) { LOG(INFO) + __FUNCTION__ + " Could not download the file"; return; // Don't attempt to play the file. } else { LOG(INFO) + __FUNCTION__ + " Could download the file"; lFilename = s2ws(newfilename); } } else { // Store the local filename away. lFilename = s2ws(filename); } // Launch the audio player. playLocalAudio(); } }
void CAppManager::ReloadRhoBundle(HWND hwnd, const char* szUrl, const char* szZipPassword) { const char *tmp_dir_name = "_tmp_"; const char *loadData = NULL; unsigned int loadSize = 0; String root_dir = rho_native_rhopath(); String tmp_unzip_dir; int errCode = RRB_UNKNOWN_ERR; root_dir.at(root_dir.length()-1) = '\\'; tmp_unzip_dir = root_dir + tmp_dir_name; if (szUrl == NULL) { LOG(ERROR) + "null url passed to ReloadRhoBundle"; return; } //trying to load file //NB: for mobile devices should use filesystem instead of RAM NetResponse resp = getNetRequest().pullData(szUrl, null); if (resp.getDataSize() > 0 && resp.getCharData()) { loadData = resp.getCharData(); loadSize = resp.getDataSize(); errCode = RRB_NONE_ERR; } else { errCode = RRB_LOADING_ERR; } //trying to unzip loaded file if (errCode == RRB_NONE_ERR) errCode = unzipRhoBundle(loadData, loadSize, szZipPassword, tmp_unzip_dir); RHODESAPP().stopApp(); //trying to delete old rhobundle if (errCode == RRB_NONE_ERR) errCode = removeOldRhoBundle(); //move new rhobundle from temporary dir if (errCode == RRB_NONE_ERR) { errCode = updateRhoBundle (root_dir, tmp_unzip_dir); } showMessage(hwnd, errCode); }
boolean CClientRegister::doRegister(CSyncEngine& oSync) { String session = oSync.loadSession(); if ( session.length() == 0 ) { m_nPollInterval = POLL_INTERVAL_INFINITE; return false; } m_nPollInterval = POLL_INTERVAL_SECONDS; String client_id = oSync.loadClientID(); if ( client_id.length() == 0 ) return false; IDBResult res = CDBAdapter::getUserDB().executeSQL("SELECT token,token_sent from client_info"); if ( !res.isEnd() ) { String token = res.getStringByIdx(0); int token_sent = res.getIntByIdx(1); if ( m_strDevicePin.compare(token) == 0 && token_sent > 0 ) { //token in db same as new one and it was already send to the server //so we do nothing return true; } } String strBody = getRegisterBody(client_id); NetResponse resp = getNet().pushData( oSync.getProtocol().getClientRegisterUrl(), strBody, &oSync ); if( resp.isOK() ) { // try { CDBAdapter::getUserDB().executeSQL("UPDATE client_info SET token_sent=?, token=?", 1, m_strDevicePin ); // } catch(Exception ex) { // LOG.ERROR("Error saving token_sent to the DB..."); // } LOG(INFO)+"Registered client sucessfully..."; return true; } else { LOG(INFO)+"Network error POST-ing device pin to the server..."; } return false; }
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; } if (m_strCallback.length() > 0) { const char* body = isOK ? "rho_callback=1&status=ok" : "rho_callback=1&status=error"; rho_net_request_with_data(RHODESAPP().canonicalizeRhoUrl(m_strCallback).c_str(), body); } RHODESAPP().setSendingLog(false); }
void CAsyncHttp::CHttpCommand::callNotify(NetResponse& resp, int nError ) { m_strResBody = "rho_callback=1"; m_strResBody += "&status="; if ( nError > 0 ) { m_strResBody += "error&error_code=" + nError; }else { if ( resp.isOK() ) m_strResBody += "ok"; else { m_strResBody += "error&error_code="; m_strResBody += convertToStringA(RhoAppAdapter.getErrorFromResponse(resp)); if ( resp.isResponseRecieved()) m_strResBody += "&http_error=" + convertToStringA(resp.getRespCode()); } String cookies = resp.getCookies(); if (cookies.length()>0) m_strResBody += "&cookies=" + URI::urlEncode(cookies); String strHeaders = makeHeadersString(); if (strHeaders.length() > 0 ) m_strResBody += "&" + strHeaders; m_strResBody += "&" + RHODESAPP().addCallbackObject( new CAsyncHttpResponse(resp, m_mapHeaders.get("content-type")), "body"); } if ( m_strCallbackParams.length() > 0 ) m_strResBody += "&" + m_strCallbackParams; if ( m_strCallback.length() > 0 ) { String strFullUrl = m_NetRequest.resolveUrl(m_strCallback); getNet().pushData( strFullUrl, m_strResBody, null ); } }
bool GoogleGeoCoding::fetchData(String const &url, void **data, size_t *datasize) { RHO_MAP_TRACE1("GoogleGeoCoding: fetchData: url=%s", url.c_str()); #ifdef ENABLE_ANDROID_NET_REQUEST mNetRequestID = mapengine_request_make(); int s = 0; int res = 0; res = mapengine_request_data(mNetRequestID, url.c_str(), data, &s); *datasize = s; return res > 0; #else NetResponse resp = getNet().doRequest("GET", url, "", 0, 0); if (!resp.isOK()) return false; *datasize = resp.getDataSize(); *data = malloc(*datasize); if (!*data) return false; memcpy(*data, resp.getCharData(), *datasize); return true; #endif }
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 = getNetRequest().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 rho_sys_app_install(const char *url) { #ifdef OS_WINDOWS_DESKTOP String sUrl = url; CFilePath oFile(sUrl); String filename = RHODESAPP().getRhoUserPath()+ oFile.getBaseName(); if (CRhoFile::isFileExist(filename.c_str()) && (CRhoFile::deleteFile(filename.c_str()) != 0)) { LOG(ERROR) + "rho_sys_app_install() file delete failed: " + filename; } else { NetRequest NetRequest; NetResponse resp = getNetRequest(&NetRequest).pullFile(sUrl, filename, NULL, NULL); if (resp.isOK()) { StringW filenameW = convertToStringW(filename); LOG(INFO) + "Downloaded " + sUrl + " to " + filename; rho_wmsys_run_appW(filenameW.c_str(), L""); } else { LOG(ERROR) + "rho_sys_app_install() download failed: " + sUrl; } } #else rho_sys_open_url(url); #endif }
void BundleUpdateThreadQueue::processCommand(IQueueCommand *pCmd) { BUCommand *cmd = (BUCommand*)pCmd; rho::String fileURL = cmd->bundle_url; rho::String fileZipLocalDir = rho::common::CFilePath::join(RHODESAPPBASE().getRhoUserPath(), "RhoBundle"); rho::String fileZipLocalPath = rho::common::CFilePath::join(fileZipLocalDir, "upgrade_bundle.zip"); const char* flz = fileZipLocalPath.c_str(); // 0 remove old files rho::common::CRhoFile::deleteFolder(fileZipLocalDir.c_str()); //rho_file_impl_delete_folder(fileZipLocalDir.c_str()); rho::common::CRhoFile::recursiveCreateDir(fileZipLocalDir.c_str(), RHODESAPPBASE().getRhoUserPath().c_str()); // 1 download zip rho::Hashtable<rho::String, rho::String> mapHeaders; mapHeaders["User-Agent"] = "Mozilla-5.0"; rho::apiGenerator::CMethodResult oResult; bool overwriteFile = true; bool createFolders = true; bool fileExists = false; NetRequest oNetRequest; NetResponse resp = getNetRequest(&oNetRequest).pullFile( fileURL, fileZipLocalPath, NULL, &mapHeaders,overwriteFile,createFolders,&fileExists); if (resp.isSuccess()) { int o; o = 9; } else { int r; r = 9; } // 2 unpack zip int zip_res = rho_sys_unzip_file(fileZipLocalPath.c_str(), ""); if (zip_res >= 0) { int o; o = 9; } else { int r; r = 9; // error // send request for full_update rho::String message = "ERROR when downloading and unpack Bundle ["; message = message + fileURL + "] ! Cancel update !"; alert_show_status("Development Extras", message.c_str(), "OK"); return; } // 3 call update bundle bool do_not_restart_app = true; bool not_thread_mode = true; bool check_filelist = true; rho::String cb_url = /*RHODESAPPBASE().getHomeUrl()*/ "http://127.0.0.1:";//37579/development/update_bundle_callback"; cb_url = cb_url + DevHTTPServer::getInstance()->getPort() + "/development/update_bundle_callback"; const char* hu = cb_url.c_str(); cmd->canContinue = false; rho_sys_replace_current_bundleEx( fileZipLocalDir.c_str(), cb_url.c_str(), do_not_restart_app, not_thread_mode, check_filelist, true ); // wait responce while (!cmd->canContinue) { sleep(30); } }
// Worker thread void NetClient::networkThread(void) { NetRequest *request = NULL; while (true) { if (needQuit) { break; } // step 1: send http request if the requestQueue isn't empty request = NULL; this->requestqMtx.lock(); //Get request task from queue if (!requestq.empty()) { request = dynamic_cast<NetRequest*>(*this->requestq.begin()); this->requestq.pop_front(); } this->requestqMtx.unlock(); if (NULL == request) { // Wait for http request tasks from main thread std::unique_lock<std::mutex> lk(this->sleepMutex); this->sleepCondition.wait(lk); continue; } // Create a HttpResponse object, the default setting is http access failed NetResponse *response = new NetResponse(request); // // // request's refcount = 2 here, it's retained by HttpRespose constructor // request->release(); // ok, refcount = 1 now, only HttpResponse hold it. int32_t responseCode = -1; this->client->set_response_buffer(response); this->client->start_request(request->getRequestData(), request->getRequestDataSize()); // retValue = this->processPostTask(request, write_data_callback, response, &responseCode); response->setResponseCode(this->client->get_error_code()); response->setSucceed(this->client->get_error_code() == 0); request->release(); // add response packet into queue this->responseqMtx.lock(); this->responseq.push_back(response); this->responseqMtx.unlock(); // resume dispatcher selector CCDirector::sharedDirector()->getScheduler()->resumeTarget(this); } asyncRequestCount -= this->requestq.size(); this->threadStarted = false; threadRunningCond.notify_one(); CCLOG("NetClient: thread exiting..."); }
void playMedia() { LOG(INFO) + __FUNCTION__ + " starting media player."; // Check that the filename is not empty or NULL. if (!szVideoFileName.empty()) { PROCESS_INFORMATION pi; StringW m_lpzFilename; if (String_startsWith(szVideoFileName, "http://") || String_startsWith(szVideoFileName, "https://")) { // Networked code LOG(INFO) + __FUNCTION__ + "Attempting to download the file. " + szVideoFileName; NetRequest oNetRequest; Hashtable<String,String> mapHeaders; bool overwriteFile = true; bool createFolders = false; bool fileExists = false; //get the file extention String szFileExtn; size_t extIndex = szVideoFileName.rfind("."); if(-1 != extIndex) { szFileExtn = szVideoFileName.substr( extIndex ); if(!szFileExtn.empty()) { String& newfilename = String("download") + szFileExtn; //delete the folder rho::common::CRhoFile::deleteFile(newfilename.c_str()); // Call the download function with the url and new filename the temp filename to be used. net::CNetRequestHolder *requestHolder = new net::CNetRequestHolder(); requestHolder->setSslVerifyPeer(false); NetResponse resp = getNetRequest(requestHolder).pullFile( szVideoFileName, newfilename, NULL, &mapHeaders,overwriteFile,createFolders,&fileExists); delete requestHolder; if (!resp.isOK()) { LOG(INFO) + __FUNCTION__ + " Could not download the file"; return; // Don't attempt to play the file. } else { LOG(INFO) + __FUNCTION__ + " Could download the file"; m_lpzFilename = s2ws(newfilename); } } else { LOG(INFO) + __FUNCTION__ + " file extention is empty "; } } else { LOG(INFO) + __FUNCTION__ + " invalid file extention "; } } else { // Local file, just change the name to a format the WM/CE understands. m_lpzFilename = s2ws(szVideoFileName); } if(!m_lpzFilename.empty()) { String szFile = rho::common::convertToStringA(m_lpzFilename.c_str()); if(rho::common::CRhoFile::isFileExist(szFile.c_str())) { /****************************************/ /* SR ID - EMBPD00142480 Issue Description - Video files are not getting played in CE devices through Rhoelements application Fix Provided - WinCE devices accepts only back slash in the path to play media files. Also CE CreateProcess API doesn't accept quates in the API for meadia file path to handle space. A conditional fix is given for WM devices and CE devices. Developer Name - Sabir VT File Name - Mediaplayer_impl.cpp Function Name - startvideo Date - 04/07/2014 */ /****************************************/ bool bRunningOnWM = false; OSVERSIONINFO osvi; memset(&osvi, 0, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osvi); bRunningOnWM = (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) || (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1); if(bRunningOnWM) { //for WM devices, we enter here /****************************************/ /* SR ID - EMBPD00128123 Issue Description - Video Files are not getting played in MediaPlayer with Native Application on WM Fix Provided - Issue was reproducing because of CreateProcess Microsoft API which donot understand the path which consists of space. Hence we need to put an extra double inverted at the front & at the end of the string. Developer Name - Abhineet Agarwal File Name - Mediaplayer_impl.cpp Function Name - startvideo Date - 09/06/2014 */ /****************************************/ m_lpzFilename = L"\"" + m_lpzFilename + L"\""; } else { //for CE devices we enter here //replace front slash with back slash if the path contains front slash m_lpzFilename = replaceString(m_lpzFilename, L"/", L"\\"); } // Launch the video player. if (!CreateProcess(L"\\windows\\WMPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi)) { // for WinCE CEPlayer we need to set a registry key to make sure it launches full screen HKEY hKey = 0; LPCWSTR subkey = L"SOFTWARE\\Microsoft\\CEPlayer"; if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0,0,&hKey) == ERROR_SUCCESS) { DWORD dwType = REG_DWORD; DWORD dwData = 1; // Set AlwaysFullSize to 1 RegSetValueEx(hKey, L"AlwaysFullSize", 0, dwType, (BYTE*)&dwData, sizeof(dwData)); RegCloseKey(hKey); } if (!CreateProcess(L"\\windows\\CEPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi)) { // if CEPlayer doesn't exist either, try VPlayer if (!CreateProcess(L"\\windows\\VPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi)) { LOG(INFO) + __FUNCTION__ + "Error launching MediaPlayer"; return; } } } //let us wait here till some once closes the process HANDLE hEvents[2] = {m_hStopMediaEvent, pi.hProcess}; DWORD dwEvent = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); if(0 == dwEvent) { TerminateProcess(pi.hProcess, -1); } LOG(INFO) + __FUNCTION__ + " windows media player is going to be terminated."; WaitForSingleObject(pi.hProcess, INFINITE); LOG(INFO) + __FUNCTION__ + " windows media player terminated."; CloseHandle(pi.hThread); CloseHandle(pi.hProcess); LOG(INFO) + __FUNCTION__ + " stopping media player."; } else { LOG(INFO) + __FUNCTION__ + " file does not exist "; } } else { LOG(INFO) + __FUNCTION__ + " file name is empty "; } } }
// Start playing a video file. virtual void startvideo( const rho::String& filename, rho::apiGenerator::CMethodResult& oResult) { // Attempt to kill the player. If we don't do this, WMP holds a lock on the file and we cannot delete it. KillPlayer(); rho::common::CRhoFile::deleteFile("download.wmv"); // Check that the filename is not empty or NULL. if (!filename.empty() && (!m_hPlayProcess)) { PROCESS_INFORMATION pi; StringW m_lpzFilename; if (String_startsWith(filename, "http://") || String_startsWith(filename, "https://")) { // Networked code LOG(INFO) + __FUNCTION__ + "Attempting to download the file. " + filename; NetRequest oNetRequest; Hashtable<String,String> mapHeaders; bool overwriteFile = true; bool createFolders = false; bool fileExists = false; String& newfilename = String("download.wmv"); // Call the download function with the url and new filename the temp filename to be used. net::CNetRequestHolder *requestHolder = new net::CNetRequestHolder(); requestHolder->setSslVerifyPeer(false); NetResponse resp = getNetRequest(requestHolder).pullFile( filename, newfilename, null, &mapHeaders,overwriteFile,createFolders,&fileExists); delete requestHolder; if (!resp.isOK()) { LOG(INFO) + __FUNCTION__ + "Could not download the file"; return; // Don't attempt to play the file. } else { LOG(INFO) + __FUNCTION__ + "Could download the file"; m_lpzFilename = s2ws(newfilename); } } else { // Local file, just change the name to a format the WM/CE understands. m_lpzFilename = s2ws(filename); } // Launch the video player. if (!CreateProcess(L"\\windows\\WMPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi)) { // for WinCE CEPlayer we need to set a registry key to make sure it launches full screen HKEY hKey = 0; LPCWSTR subkey = L"SOFTWARE\\Microsoft\\CEPlayer"; if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0,0,&hKey) == ERROR_SUCCESS) { DWORD dwType = REG_DWORD; DWORD dwData = 1; // Set AlwaysFullSize to 1 RegSetValueEx(hKey, L"AlwaysFullSize", 0, dwType, (BYTE*)&dwData, sizeof(dwData)); RegCloseKey(hKey); } if (!CreateProcess(L"\\windows\\CEPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi)) { // if CEPlayer doesn't exist either, try VPlayer if (!CreateProcess(L"\\windows\\VPlayer.exe", m_lpzFilename.c_str(), NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi)) { LOG(INFO) + __FUNCTION__ + "Error launching MediaPlayer"; return; } } m_hPlayProcess = pi.hProcess; m_hPlayThread = pi.hThread; } m_hPlayProcess = pi.hProcess; m_hPlayThread = pi.hThread; } }