diff -r e8e63152f320 -r 2a9601315dfc javaextensions/midppush/pushregistryplugin/src/pushregistryhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/midppush/pushregistryplugin/src/pushregistryhandler.cpp Mon May 03 12:27:20 2010 +0300 @@ -0,0 +1,1219 @@ +/* +* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include +#include +#include + +#include "pushregistryhandler.h" +#include "coreinterface.h" +#include "rtcinterface.h" +#include "commsendpoint.h" +#include "commsmessage.h" +#include "pushregistrymessages.h" +#include "javacommonutils.h" +#include "logger.h" +#include "pushconstant.h" +#include "pushexception.h" +#include "pusherrorcodes.h" +#include "pushdbhandler.h" +#include "pushdatacontainer.h" +#include "pushalarmhandler.h" +#include "javauid.h" +#include "booteventprovidermessages.h" +#include "mmceventprovidermessages.h" + +using namespace java::push; +using namespace java::captain; +using namespace java::comms; +using namespace java::util; +using namespace java::fileutils; +using namespace std; + +/*extern "C"*/ +#ifdef __SYMBIAN32__ +ExtensionPluginInterface* getExtensionPlugin() +{ +#else +extern "C" ExtensionPluginInterface* getExtensionPlugin() +{ +#endif + return new PushRegistryHandler(); +} + +/** + * + */ +OS_EXPORT PushRegistryHandler::PushRegistryHandler() + :mCore(NULL),mPushDbHandler(new PushDBHandler()),mPushDataContainer(NULL), + mPushAlarmHandler(NULL),mConnCompletedTimerContainer(NULL) +{ + JELOG2(EJavaPush); + //LOG1(EJavaPush,EInfo,"PushRegistryHandler(), this: %d",this); +} + +/** + * + */ +OS_EXPORT PushRegistryHandler::~PushRegistryHandler() +{ + JELOG2(EJavaPush); + mDriveInfo.clear(); + //LOG1(EJavaPush,EInfo,"~PushRegistryHandler(), this: %d",this); +} + +/** + * + */ +void PushRegistryHandler::startPlugin(java::captain::CoreInterface* aCore) +{ + JELOG2(EJavaPush); + + try + { + mCore = aCore; + mCore->getComms()->registerListener(PLUGIN_ID_PUSH_REGISTRY_C,this); + mPushDataContainer.reset(new PushDataContainer(*mCore,*mPushDbHandler)); + mPushAlarmHandler.reset(new PushAlarmHandler(*mCore,*this,*mPushDbHandler)); + mConnCompletedTimerContainer.reset + (new PushConnCompletedTimerContainer(*aCore->getTimerServer(),*this)); + } + catch (...) + { + ELOG(EJavaPush,"ERROR!!! Exception caught in the PushRegistryHandler::start() operation"); + } +} + +/** + * + */ +void PushRegistryHandler::stopPlugin() +{ + JELOG2(EJavaPush); + + mCore->getComms()->unregisterListener(PLUGIN_ID_PUSH_REGISTRY_C,this); +} + +/** + * + */ +ApplicationRuntimeEventsInterface* PushRegistryHandler::getApplicationRuntimeListener() +{ + return this; +} + +/** + * + */ +ApplicationManagementEventsInterface* PushRegistryHandler::getApplicationManagementListener() +{ + return this; +} + +/** + * + */ +EventConsumerInterface* PushRegistryHandler::getEventConsumer() +{ + return this; +} + +/** + * + */ +void PushRegistryHandler::processMessage(CommsMessage& aMessage) +{ + JELOG2(EJavaPush); + + switch (aMessage.getMessageId()) + { + case IPC_PR_GET_ALL_PUSH_REGS: + { + handleGetAllPushRegsMsg(aMessage); + break; + } + case IPC_PR_REGISTER_DYNAMIC_PUSH_CONN: + { + handleRegDynamicPushConnMsg(aMessage); + break; + } + case IPC_PR_UNREGISTER_DYNAMIC_PUSH_CONN: + { + handleUnregDynamicPushConnMsg(aMessage); + break; + } + case IPC_PR_REGISTER_ALARM: + { + handleRegisterAlarmMsg(aMessage); + break; + } + case IPC_PR_ALL_CONNS_FAILED: + { + handleAllConnsFailedMsg(aMessage); + break; + } + case IPC_PR_PENDING_STATUS: + { + handlePendingStatusMsg(aMessage); + break; + } + case IPC_PR_LIST_CONNECTIONS: + { + handleListConnectionsMsg(aMessage); + break; + } + case IPC_PR_DATA_OF_PUSH_CONN_QUERY: + { + handleDataOfPushConnQueryMsg(aMessage); + break; + } + case IPC_PR_PUSH_URI_STARTS_WITH_QUERY: + { + handlePushUriStartsWithQueryMsg(aMessage); + break; + } + case IPC_PR_CONN_COMPLETED: + { + handleConnCompletedMsg(aMessage); + break; + } + + default: + ELOG1(EJavaPush, "ERROR!!! Unsupported method arrives to processMessage(): %d", + aMessage.getMessageId()); + }//end switch +} + +/** + * + */ +void PushRegistryHandler::arLaunched(const Uid& /*aUID*/, const int& /*aRuntimeCommsAddress*/) +{ + JELOG2(EJavaPush); + //Launch of the application does not interest push framework. +} + +/** + * + */ +void PushRegistryHandler::arTerminated(const Uid& aUID, const int& aExitCode) +{ + JELOG2(EJavaPush); + + LOG1WSTR(EJavaPush,EInfo,"arTerminated(), Uid: %s",aUID.toString()); + LOG1(EJavaPush,EInfo,"arTerminated(), aExitCode: %d",aExitCode); + + //MIDlet has been terminated so pending status of all its push connections + //can be set to "not active" state. + mPushDataContainer->clearPendingStatusesOfMidlet(aUID); + + bool flag = mPushDataContainer->isPushConnections(aUID); + if (true == flag) + { + //aExitCode is non-zero if runtime has crashed. In that case MIDlet + //is not launched as listening mode. + if (0 != aExitCode) + { + ELOG1(EJavaPush,"ERROR!!! arTerminated(), aExitCode: %d",aExitCode); + mPushDataContainer->setMidletDoNotLaunchList(aUID); + } + if (false == mPushDataContainer->isMidletInDoNotLaunchList(aUID)) + { + //Launching an application. + LOG(EJavaPush,EInfo,"arTerminated(), launching application in push mode"); + launchMidlet(aUID,java::captain::RTC_LAUNCH_TYPE_PUSH_C); + } + }//end if(true == flag) +} + +/** + * + */ +void PushRegistryHandler::amAdded(const uids_t& aUids) +{ + JELOG2(EJavaPush); + + //JavaCaptain calls this method when new application has been installed or + //application's uid has been changed in the upgrade. + for (uids_t::const_iterator iter = aUids.begin(); iter != aUids.end(); ++iter) + { + //Alarm case have to be checked in this situation because uid of the alarm might + //be changed in the upgrade. + readAppData((*iter),true); + }//end for +} + +/** + * + */ +void PushRegistryHandler::amUpdated(const uids_t& aUids) +{ + JELOG2(EJavaPush); + + //JavaCaptain calls this operation when application's data has been updated + //by Installer. In this situation uid of the appplication has not been updated. + for (uids_t::const_iterator iter = aUids.begin(); iter != aUids.end(); ++iter) + { + deleteAppData((*iter),false); + //Alarm does not have to be checked in this situation because uid of the + //application has not been changed and Installer has not changed alarm. + readAppData((*iter),false); + } +} + +/** + * + */ +void PushRegistryHandler::amDeleted(const uids_t& aUids) +{ + JELOG2(EJavaPush); + + //JavaCaptain calls this method when application has been uninstalled. + //Note: This is called also in the upgrade of the application if application's + //uid has been changed. + for (uids_t::const_iterator iter = aUids.begin(); iter != aUids.end(); ++iter) + { + deleteAppData((*iter),true); + }//end for +} + +/** + * + */ +void PushRegistryHandler::event(const std::string& eventProvider, + java::comms::CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + try + { + if (eventProvider == BOOT_EVENT_PROVIDER) + { + LOG(EJavaPush, EInfo, "PushRegistryHandler::event() boot event received"); + int bootType = 0; + getBootMessageParams(aMsg, bootType); + //Read initial drive status. After that drive info status is updated + //when mmc is inserted/deleted. JavaCaptain sends MMC_EVENT_PROVIDER event when mmc + //status changes. + mDriveInfo.clear(); + DriveUtilities::getAccesibleDrives(mDriveInfo); + startPushMidlets(); + mPushAlarmHandler->readAndStartAlarms(); + } + else if (eventProvider == MMC_EVENT_PROVIDER) + { + int operation = 0; + driveInfo di; + getMmcChangedMessageParams(aMsg, operation, di); + LOG1( + EJavaCaptain, + EInfo, + "PushRegistryHandler::event() mmc event received (operation=%d)", + operation); + + switch (operation) + { + case DriveListenerInterface::REMOVABLE_MEDIA_INSERTED_C: + manageDriveInsertion(di); + break; + case DriveListenerInterface::REMOVABLE_MEDIA_REMOVED_C: + manageDriveRemoval(di); + break; + } + } + } + catch (ExceptionBase& ex) + { + ELOG1(EJavaPush,"ERROR!!! PushRegistryHandler::event(): %s",ex.toString().c_str()); + } + catch (...) + { + ELOG(EJavaPush,"ERROR!!! Exception caught in the PushRegistryHandler::event() operation"); + } +} + +/** + * + */ +void PushRegistryHandler::connCompletedTimerExpired(const java::comms::CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + try + { + CommsMessage unRegCompleted; + unRegCompleted.setSender(IPC_ADDRESS_JAVA_CAPTAIN_C); + unRegCompleted.setReceiver(aMsg.getSender()); + unRegCompleted.setModuleId(PLUGIN_ID_PUSH_CONTROLLER_C); + unRegCompleted.setMessageId(IPC_PR_CONN_MANAGED_BY_OTHER_MIDLET); + int retValue = mCore->getComms()->send(unRegCompleted); + if (0 != retValue) + { + //Exception is not thrown from this situation. + std::string errTxt("Sending IPC_PR_CONN_MANAGED_BY_OTHER_MIDLET comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } + } + catch (...) + { + ELOG(EJavaPush, + "ERROR!!! Exception caught in the PushRegistryHandler::connCompletedTimerExpired() operation"); + } +} + +/** + * + */ +void PushRegistryHandler::handleGetAllPushRegsMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + Uid uid; + try + { + readUidArg(aMsg,"IPC_PR_GET_ALL_PUSH_REGS",uid); + std::list listOfPushRegs; + mPushDataContainer->getPushRegsOfMidlet(uid,listOfPushRegs); + + CommsMessage listOfPushRegsMsg; + listOfPushRegsMsg.setSender(IPC_ADDRESS_JAVA_CAPTAIN_C); + listOfPushRegsMsg.setReceiver(aMsg.getSender()); + listOfPushRegsMsg.setModuleId(PLUGIN_ID_PUSH_CONTROLLER_C); + listOfPushRegsMsg.setMessageId(IPC_PR_LIST_OF_ALL_PUSH_REGS); + listOfPushRegsMsg.setMessageRef(aMsg.getMessageRef()); + + listOfPushRegsMsg << uid; + listOfPushRegsMsg << NO_ERROR; + listOfPushRegsMsg << ""; + std::list::iterator iter; + for (iter = listOfPushRegs.begin(); iter != listOfPushRegs.end(); ++iter) + { + LOG1(EJavaPush,EInfo, "handleGetAllPushRegsMsg() URI: %S",iter->mUri.c_str()); + listOfPushRegsMsg << iter->mUri; + listOfPushRegsMsg << iter->mFilter; + }//end for + + int retValue = mCore->getComms()->send(listOfPushRegsMsg); + if (0 != retValue) + { + //Exception is not thrown from this situation. + std::string errTxt("Sending IPC_PR_LIST_OF_ALL_PUSH_REGS comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } + } + catch (ExceptionBase& ex) + { + sendCommsResponseInErrorCase(ex,IPC_PR_LIST_OF_ALL_PUSH_REGS,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } + catch (...) + { + ExceptionBase tmpBase(UNKNOWN_ERROR,"Unknown exception caught", + __FILE__,__FUNCTION__,__LINE__); + sendCommsResponseInErrorCase(tmpBase,IPC_PR_LIST_OF_ALL_PUSH_REGS,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } +} + +/** + * + */ +void PushRegistryHandler::handleRegDynamicPushConnMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + Uid uid; + try + { + readUidArg(aMsg,"IPC_PR_REGISTER_DYNAMIC_PUSH_CONN",uid); + + std::wstring pushUri; + readWStrArg(aMsg,"IPC_PR_REGISTER_DYNAMIC_PUSH_CONN",pushUri); + + std::wstring midletName; + readWStrArg(aMsg,"IPC_PR_REGISTER_DYNAMIC_PUSH_CONN",midletName); + + std::wstring filter; + readWStrArg(aMsg,"IPC_PR_REGISTER_DYNAMIC_PUSH_CONN",filter); + + int isUidOfThisMidlet = readIntAsBooleanArg(aMsg,"IPC_PR_REGISTER_DYNAMIC_PUSH_CONN"); + + mPushDataContainer->storeDynamicPushRegistration(uid,pushUri,midletName,filter); + + if (0 == isUidOfThisMidlet) + { + LOG1WSTR(EJavaPush,EInfo,"handleRegDynamicPushConnMsg() Uid: %s",uid.toString()); + mConnCompletedTimerContainer->setTimer(pushUri,aMsg); + launchMidlet(uid,java::captain::RTC_LAUNCH_TYPE_PUSH_C); + } + + sendCommsResponseInSuccessCase(IPC_PR_REGISTER_DYNAMIC_PUSH_CONN_REPLY,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } + catch (ExceptionBase& ex) + { + sendCommsResponseInErrorCase(ex,IPC_PR_REGISTER_DYNAMIC_PUSH_CONN_REPLY,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } + catch (...) + { + ExceptionBase tmpBase(UNKNOWN_ERROR,"Unknown exception caught", + __FILE__,__FUNCTION__,__LINE__); + sendCommsResponseInErrorCase(tmpBase,IPC_PR_REGISTER_DYNAMIC_PUSH_CONN_REPLY,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } +} + +/** + * + */ +void PushRegistryHandler::handleUnregDynamicPushConnMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + Uid uid; + try + { + readUidArg(aMsg,"IPC_PR_UNREGISTER_DYNAMIC_PUSH_CONN",uid); + std::wstring pushUri; + readWStrArg(aMsg,"IPC_PR_UNREGISTER_DYNAMIC_PUSH_CONN",pushUri); + int isUidOfThisMidlet = readIntAsBooleanArg(aMsg,"IPC_PR_UNREGISTER_DYNAMIC_PUSH_CONN"); + + mPushDataContainer->unregisterDynamicPushRegistration(uid,pushUri); + + if (0 == isUidOfThisMidlet) + { + LOG1WSTR(EJavaPush,EInfo,"handleUnregDynamicPushConnMsg() Uid: %s",uid.toString()); + mConnCompletedTimerContainer->setTimer(pushUri,aMsg); + launchMidlet(uid,java::captain::RTC_LAUNCH_TYPE_PUSH_C); + } + + sendCommsResponseInSuccessCase(IPC_PR_UNREGISTER_DYNAMIC_PUSH_CONN_REPLY,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } + catch (ExceptionBase& ex) + { + sendCommsResponseInErrorCase(ex,IPC_PR_UNREGISTER_DYNAMIC_PUSH_CONN_REPLY,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } + catch (...) + { + ExceptionBase tmpBase(UNKNOWN_ERROR,"Unknown exception caught", + __FILE__,__FUNCTION__,__LINE__); + sendCommsResponseInErrorCase(tmpBase,IPC_PR_UNREGISTER_DYNAMIC_PUSH_CONN_REPLY,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } +} + +/** + * + */ +void PushRegistryHandler::handleRegisterAlarmMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + Uid suiteUid; + long long retWakeupTime = -1LL; + try + { + readUidArg(aMsg,"IPC_PR_REGISTER_ALARM",suiteUid); + + long long alarmTime = readLongLongArg(aMsg,"IPC_PR_REGISTER_ALARM"); + + std::wstring classNameOfMidlet; + readWStrArg(aMsg,"IPC_PR_REGISTER_ALARM",classNameOfMidlet); + + int isUidOfThisMidlet = readIntAsBooleanArg(aMsg,"IPC_PR_REGISTER_ALARM"); + bool isUidOfThisMidletAsBool = false; + if (1 == isUidOfThisMidlet) + isUidOfThisMidletAsBool = true; + + const java::util::Uid& midletUid = mPushDataContainer->getMidletUid(suiteUid,classNameOfMidlet); + retWakeupTime = mPushAlarmHandler->setAlarm(midletUid,alarmTime,isUidOfThisMidletAsBool); + sendRegisterAlarmReply(aMsg.getSender(),suiteUid,retWakeupTime,aMsg.getMessageRef()); + } + catch (ExceptionBase& ex) + { + sendRegisterAlarmReplyInErrorCase(ex,aMsg.getSender(),suiteUid,aMsg.getMessageRef()); + } + catch (...) + { + ExceptionBase tmpBase(UNKNOWN_ERROR,"Unknown exception caught", + __FILE__,__FUNCTION__,__LINE__); + sendRegisterAlarmReplyInErrorCase(tmpBase,aMsg.getSender(),suiteUid,aMsg.getMessageRef()); + } +} + +/** + * + */ +void PushRegistryHandler::handleAllConnsFailedMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + try + { + Uid uid; + readUidArg(aMsg,"IPC_PR_ALL_CONNS_FAILED",uid); + mPushDataContainer->setMidletDoNotLaunchList(uid); + RtcInterface* rtc = mCore->getRtc(); + rtc->terminate(uid); + } + catch (...) + { + ELOG(EJavaPush,"ERROR!!! Exception occurs in the handling a IPC_PR_ALL_CONNS_FAILED comms msg"); + } +} + +/** + * + */ +void PushRegistryHandler::handlePendingStatusMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + try + { + Uid uid; + readUidArg(aMsg,"IPC_PR_PENDING_STATUS",uid); + + std::wstring pushUri; + readWStrArg(aMsg,"IPC_PR_PENDING_STATUS",pushUri); + + int msgWaitsHandling = readIntAsBooleanArg(aMsg,"IPC_PR_PENDING_STATUS"); + bool msgWaitsHandlingFlag = false; + if (1 == msgWaitsHandling) + msgWaitsHandlingFlag = true; + + mPushDataContainer->setPendingStatusOfConn(uid,pushUri,msgWaitsHandlingFlag); + } + catch (...) + { + ELOG(EJavaPush,"ERROR!!! Exception occurs in the handling a IPC_PR_PENDING_STATUS comms msg"); + } +} + +/** + * + */ +void PushRegistryHandler::handleListConnectionsMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + Uid uid; + try + { + readUidArg(aMsg,"IPC_PR_LIST_CONNECTIONS",uid); + int availableConns = readIntAsBooleanArg(aMsg,"IPC_PR_LIST_CONNECTIONS"); + bool allConnsFlag = true; + if (1 == availableConns) + allConnsFlag = false; + + std::list listOfPushUris; + mPushDataContainer->getPushRegsOfMidletSuite(uid,allConnsFlag,listOfPushUris); + + CommsMessage listConnsReply; + listConnsReply.setSender(IPC_ADDRESS_JAVA_CAPTAIN_C); + listConnsReply.setReceiver(aMsg.getSender()); + listConnsReply.setModuleId(PLUGIN_ID_PUSH_CONTROLLER_C); + listConnsReply.setMessageId(IPC_PR_LIST_CONNECTIONS_REPLY); + listConnsReply.setMessageRef(aMsg.getMessageRef()); + listConnsReply << uid; + listConnsReply << NO_ERROR; + listConnsReply << ""; + std::list::iterator iter; + for (iter = listOfPushUris.begin(); iter != listOfPushUris.end(); ++iter) + { + LOG1WSTR(EJavaPush,EInfo,"handleListConnectionsMsg() URI: %s",(*iter)); + listConnsReply << (*iter); + }//end for + + int retValue = mCore->getComms()->send(listConnsReply); + if (0 != retValue) + { + //Exception is not thrown from this situation. + std::string errTxt("Sending IPC_PR_LIST_CONNECTIONS_REPLY comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } + } + catch (ExceptionBase& ex) + { + sendCommsResponseInErrorCase(ex,IPC_PR_LIST_CONNECTIONS_REPLY,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } + catch (...) + { + ExceptionBase tmpBase(UNKNOWN_ERROR,"Unknown exception caught", + __FILE__,__FUNCTION__,__LINE__); + sendCommsResponseInErrorCase(tmpBase,IPC_PR_LIST_CONNECTIONS_REPLY,uid,aMsg.getSender(), + aMsg.getMessageRef()); + } +} + +/** + * + */ +void PushRegistryHandler::handleDataOfPushConnQueryMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + Uid suiteUid; + string nameOfMsg("IPC_PR_DATA_OF_PUSH_CONN_QUERY"); + try + { + readUidArg(aMsg,nameOfMsg,suiteUid); + std::wstring uriAsStr; + readWStrArg(aMsg,nameOfMsg,uriAsStr); + int queryArg = readIntArg(aMsg,nameOfMsg); + + std::wstring retStr; + if (FILTER_OF_PUSH_CONN == (EPushInfoQueryParams) queryArg) + retStr = mPushDataContainer->getFilterOfPushConn(suiteUid,uriAsStr); + else if (CLASSNAME_OF_PUSH_CONN == (EPushInfoQueryParams) queryArg) + retStr = mPushDataContainer->getClassNameOfPushConn(suiteUid,uriAsStr); + else + { + throw PushException(INCORRECT_COMMS_MSG,"Incorrect value in the query param", + __FILE__,__FUNCTION__,__LINE__); + } + + CommsMessage replyMsg; + replyMsg.setSender(IPC_ADDRESS_JAVA_CAPTAIN_C); + replyMsg.setReceiver(aMsg.getSender()); + replyMsg.setModuleId(PLUGIN_ID_PUSH_CONTROLLER_C); + replyMsg.setMessageId(IPC_PR_DATA_OF_PUSH_CONN_QUERY_REPLY); + replyMsg.setMessageRef(aMsg.getMessageRef()); + replyMsg << suiteUid; + replyMsg << NO_ERROR; + replyMsg << ""; + replyMsg << retStr; + + int retValue = mCore->getComms()->send(replyMsg); + if (0 != retValue) + { + //Exception is not thrown from this situation. + std::string errTxt("Sending IPC_PR_DATA_OF_PUSH_CONN_QUERY_REPLY comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } + } + catch (ExceptionBase& ex) + { + sendCommsResponseInErrorCase(ex,IPC_PR_DATA_OF_PUSH_CONN_QUERY_REPLY,suiteUid, + aMsg.getSender(),aMsg.getMessageRef()); + } + catch (...) + { + ExceptionBase tmpBase(UNKNOWN_ERROR,"Unknown exception caught", + __FILE__,__FUNCTION__,__LINE__); + sendCommsResponseInErrorCase(tmpBase,IPC_PR_DATA_OF_PUSH_CONN_QUERY_REPLY,suiteUid, + aMsg.getSender(),aMsg.getMessageRef()); + } +} + +/** + * + */ +void PushRegistryHandler::handlePushUriStartsWithQueryMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + try + { + std::wstring uriAsStr; + readWStrArg(aMsg,"IPC_PR_PUSH_URI_STARTS_WITH_QUERY",uriAsStr); + + Uid suiteUid; + bool uriFound = mPushDataContainer->getSuiteUidByBaseUri(uriAsStr,suiteUid); + int status = -1; + if (true == uriFound) + status = 0; + + CommsMessage replyMsg; + replyMsg.replyTo(aMsg); + replyMsg.setMessageId(IPC_PR_PUSH_URI_STARTS_WITH_QUERY_REPLY); + replyMsg << status; + if (0 == status) + replyMsg << suiteUid; + int retValue = mCore->getComms()->send(replyMsg); + if (0 != retValue) + { + //Exception is not thrown from this situation. + std::string errTxt("Sending IPC_PR_PUSH_URI_STARTS_WITH_QUERY_REPLY comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } + } + catch (...) + { + //Exceptions should not been thrown in this operation. + sendPushUriStartsWithQueryReplyInErrorCase(aMsg); + } +} + +/** + * + */ +void PushRegistryHandler::handleConnCompletedMsg(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + std::wstring pushUri; + readWStrArg(aMsg,"IPC_PR_UNREG_COMPLETED",pushUri); + + mConnCompletedTimerContainer->cancelTimer(pushUri); +} + +/** + * + */ +void PushRegistryHandler::sendCommsResponseInSuccessCase(int aMsgId,const Uid& aUid, + int aSenderOfOrigMsg,int aMsgRef) +{ + JELOG2(EJavaPush); + + CommsMessage replyMsg; + replyMsg.setSender(IPC_ADDRESS_JAVA_CAPTAIN_C); + replyMsg.setReceiver(aSenderOfOrigMsg); + replyMsg.setModuleId(PLUGIN_ID_PUSH_CONTROLLER_C); + replyMsg.setMessageId(aMsgId); + replyMsg.setMessageRef(aMsgRef); + + replyMsg << aUid; + replyMsg << NO_ERROR; + replyMsg << ""; + int retValue = mCore->getComms()->send(replyMsg); + if (0 != retValue) + { + std::string errTxt("Sending a comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } +} + +/** + * + */ +void PushRegistryHandler::sendRegisterAlarmReply(int aSenderOfOrigMsg,const Uid& aUid, + const long long& aTimeInMilliSecs,int aMsgRef) +{ + JELOG2(EJavaPush); + + CommsMessage replyMsg; + replyMsg.setSender(IPC_ADDRESS_JAVA_CAPTAIN_C); + replyMsg.setReceiver(aSenderOfOrigMsg); + replyMsg.setModuleId(PLUGIN_ID_PUSH_CONTROLLER_C); + replyMsg.setMessageId(IPC_PR_REGISTER_ALARM_REPLY); + replyMsg.setMessageRef(aMsgRef); + + replyMsg << aUid; + replyMsg << NO_ERROR; + replyMsg << ""; + replyMsg << aTimeInMilliSecs; + int retValue = mCore->getComms()->send(replyMsg); + if (0 != retValue) + { + std::string errTxt("Sending a comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } +} + +/** + * + */ +void PushRegistryHandler::sendRegisterAlarmReplyInErrorCase(ExceptionBase& aException, + int aSenderOfOrigMsg, + const Uid& aUid, + int aMsgRef) +{ + JELOG2(EJavaPush); + std::string errTxt = aException.toString(); + int errCode = aException.mErrCode; + + CommsMessage replyMsg; + replyMsg.setSender(IPC_ADDRESS_JAVA_CAPTAIN_C); + replyMsg.setReceiver(aSenderOfOrigMsg); + replyMsg.setModuleId(PLUGIN_ID_PUSH_CONTROLLER_C); + replyMsg.setMessageId(IPC_PR_REGISTER_ALARM_REPLY); + replyMsg.setMessageRef(aMsgRef); + + long long tmpTimeValue = 0LL; + replyMsg << aUid; + replyMsg << errCode; + replyMsg << errTxt; + replyMsg << tmpTimeValue; + int retValue = mCore->getComms()->send(replyMsg); + if (0 != retValue) + { + std::string errTxt("Sending an IPC_PR_REGISTER_ALARM_REPLY request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } +} + +/** + * + */ +void PushRegistryHandler::sendCommsResponseInErrorCase(ExceptionBase& aException, + int aMsgId,const Uid& aUid, + int aSenderOfOrigMsg, + int aMsgRef) +{ + JELOG2(EJavaPush); + std::string errTxt = aException.toString(); + int errCode = aException.mErrCode; + + CommsMessage replyMsg; + replyMsg.setSender(IPC_ADDRESS_JAVA_CAPTAIN_C); + replyMsg.setReceiver(aSenderOfOrigMsg); + replyMsg.setModuleId(PLUGIN_ID_PUSH_CONTROLLER_C); + replyMsg.setMessageId(aMsgId); + replyMsg.setMessageRef(aMsgRef); + + replyMsg << aUid; + replyMsg << errCode; + replyMsg << errTxt; + //This error is ignored because original error is wanted to show to the user. + int retValue = mCore->getComms()->send(replyMsg); + if (0 != retValue) + { + std::string errTxt("Sending a comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } +} + +/** + * + */ +void PushRegistryHandler::sendPushUriStartsWithQueryReplyInErrorCase(CommsMessage& aMsg) +{ + JELOG2(EJavaPush); + + try + { + CommsMessage replyMsg; + replyMsg.replyTo(aMsg); + replyMsg.setMessageId(IPC_PR_PUSH_URI_STARTS_WITH_QUERY_REPLY); + replyMsg << (int) -1; + int retValue = mCore->getComms()->send(replyMsg); + if (0 != retValue) + { + //Exception is not thrown from this situation. + std::string errTxt("Sending IPC_PR_PUSH_URI_STARTS_WITH_QUERY_REPLY comms request failed: "); + errTxt.append(java::util::JavaCommonUtils::intToString(retValue)); + ELOG1(EJavaPush, "ERROR!!! %s",errTxt.c_str()); + } + } + catch (...) + { + ELOG(EJavaPush,"ERROR!!! Unexpected exception caught in sendPushUriStartsWithQueryReplyInErrorCase() operation"); + } +} + +/** + * + */ +void PushRegistryHandler::startPushMidlets() +{ + JELOG2(EJavaPush); + //Retrieving all push registrations from the db. + std::set uidList; + mPushDataContainer->getIdsOfMidlets(uidList); + std::set::iterator iter; + for (iter = uidList.begin(); iter != uidList.end(); ++iter) + { + LOG1WSTR(EJavaPush,EInfo,"startPushMidlets() Uid: %s",iter->toString()); + launchMidlet((*iter),java::captain::RTC_LAUNCH_TYPE_PUSH_C); + } +} + +/** + * + */ +void PushRegistryHandler::deleteAppData(const java::util::Uid& aUid,const bool& aDeleteAlarm) +{ + JELOG2(EJavaPush); + if (true == aDeleteAlarm) + { + //Cancelling pending alarm. + mPushAlarmHandler->cancelAlarm(aUid); + } + //Removing push registrations of the application from the internal cache. + mPushDataContainer->removeApp(aUid); +} + +/** + * + */ +void PushRegistryHandler::readAppData(const java::util::Uid& aUid,const bool& aUpdateAlarm) +{ + JELOG2(EJavaPush); + if (true == aUpdateAlarm) + { + mPushAlarmHandler->readAndStartAlarms(aUid); + } + mPushDataContainer->readAppDataFromDb(aUid); + bool isPushConns = mPushDataContainer->isPushConnections(aUid); + if (true == isPushConns) + { + LOG1WSTR(EJavaPush,EInfo,"readAppData() Uid: %s",aUid.toString()); + launchMidlet(aUid,java::captain::RTC_LAUNCH_TYPE_PUSH_C); + } +} + +/** + * + */ +void PushRegistryHandler::manageDriveInsertion(const driveInfo& aDriveInfo) +{ + JELOG2(EJavaPush); + + //On the safe side, first is checked whether a new drive already exists + //in the mDriveInfo container. This should not never happened. + removeDriveFromContainer(aDriveInfo); + + //Next a new drive is added to the mDriveInfo container. + mDriveInfo.push_back(aDriveInfo); + + //Managing MIDlets which alarm was expired when added drive was not in the device. + mPushAlarmHandler->handleDriveWasMissingMidlets(aDriveInfo.iId); + + //Launching all push MIDlets in the push mode which has been installed to a new drive. + startOrKillMidlet(aDriveInfo.iId,false); +} + +/** + * + */ +void PushRegistryHandler::manageDriveRemoval(const driveInfo& aDriveInfo) +{ + JELOG2(EJavaPush); + + //First is removed drive from the mDriveInfo container. + removeDriveFromContainer(aDriveInfo); + + //Killing all push MIDlets which are installed to the removed drive. + startOrKillMidlet(aDriveInfo.iId,true); +} + +/** + * + */ +void PushRegistryHandler::startOrKillMidlet(const unsigned int aMediaId, + bool aTerminateMidlet) +{ + JELOG2(EJavaPush); + + //Retrieving uids of MIDlets installed to the added drive. + list uidList; + mPushDataContainer->getMidletUidsByMediaId(aMediaId,uidList); + + //Start push MIDlets in push listening mode. + RtcInterface* rtc = mCore->getRtc(); + for (list::const_iterator iter = uidList.begin(); iter != uidList.end(); ++iter) + { + if (false == aTerminateMidlet) + { + if (true == mPushDataContainer->isPushConnections((*iter))) + { + //MIDlet is removed from "do not launch" list also when + //mmc(wherein MIDlet has been installed) is inserted to the device. + mPushDataContainer->removeMidletFromDoNotLaunchList((*iter)); + LOG1WSTR(EJavaPush,EInfo,"startOrKillMidlet() launch Uid: %s",iter->toString()); + rtc->launch(rtcLaunchInfo((*iter),java::captain::RTC_LAUNCH_TYPE_PUSH_C)); + } + } + else + { + mPushDataContainer->clearPendingStatusesOfMidlet((*iter)); + LOG1WSTR(EJavaPush,EInfo,"startOrKillMidlet() terminate Uid: %s",iter->toString()); + rtc->terminate((*iter)); + } + } + uidList.clear(); +} + +/** + * + */ +void PushRegistryHandler::removeDriveFromContainer(const driveInfo& aDriveInfo) +{ + for (driveInfos::iterator iter = mDriveInfo.begin(); iter != mDriveInfo.end();) + { + //Root path is unique for every drive and it is always available + //in the driveInfo so it is safe to compare equality of two driveInfo objects + //with this value. + //On the safe side, a whole list is looped through. + if (aDriveInfo.iRootPath == iter->iRootPath) + { + mDriveInfo.erase(iter); + continue; + } + else + ++iter; + }//end for +} + +/** + * + */ +bool PushRegistryHandler::isDriveAvailable(int aMediaId) +{ + JELOG2(EJavaPush); + + driveInfos::iterator iter = mDriveInfo.begin(); + for (; iter != mDriveInfo.end(); ++iter) + { + if (aMediaId == iter->iId) + { + //iIsPresent should never be false when it is added to the mDriveInfo + //container. + if (true == iter->iIsPresent) + return true; + } + }//end for + return false; +} + +/** + * + */ +bool PushRegistryHandler::launchMidlet(const Uid& aMidletUid, + const int& aLaunchType) +{ + JELOG2(EJavaPush); + + int mediaId = mPushDataContainer->getMediaIdByMidletUid(aMidletUid); + + bool isDriveAvailableFlag = false; + //Media id 0 is reserved for non-removable drives (e.g. c:\ drive) so + //we does not have to check drive's availability in that case. + if (0 == mediaId) + isDriveAvailableFlag = true; + else + { + if (UNDEFINED_MEDIA_ID != mediaId) + isDriveAvailableFlag = isDriveAvailable(mediaId); + } + + if ((MEDIA_ID_IN_LINUX == mediaId) || (true == isDriveAvailableFlag)) + { + LOG2(EJavaPush,EInfo,"MIDlet launched UID: %S, launch type: %d", + aMidletUid.toString().c_str(),aLaunchType); + RtcInterface* rtc = mCore->getRtc(); + rtc->launch(rtcLaunchInfo(aMidletUid,aLaunchType)); + return true; + } + return false; +} + +/** + * + */ +int PushRegistryHandler::getMediaIdByMidletUid(const Uid& aMidletUid) +{ + JELOG2(EJavaPush); + + return mPushDataContainer->getMediaIdByMidletUid(aMidletUid); +} + +/** + * + */ +void PushRegistryHandler::readUidArg(CommsMessage& aMsg,const std::string& aMsgName,Uid& aUid) +{ + if (!(aMsg >> aUid)) + { + std::string errTxt("Cannot read UID from "); + errTxt.append(aMsgName); + errTxt.append(" msg"); + ELOG1(EJavaPush,"ERROR!!! %s",errTxt.c_str()); + throw PushException(INCORRECT_COMMS_MSG,errTxt,__FILE__,__FUNCTION__,__LINE__); + } +} + +/** + * + */ +void PushRegistryHandler::readWStrArg(CommsMessage& aMsg,const std::string& aMsgName,std::wstring& aStr) +{ + if (!(aMsg >> aStr)) + { + std::string errTxt("Cannot read wstring from "); + errTxt.append(aMsgName); + errTxt.append(" msg"); + ELOG1(EJavaPush,"ERROR!!! %s",errTxt.c_str()); + throw PushException(INCORRECT_COMMS_MSG,errTxt,__FILE__,__FUNCTION__,__LINE__); + } +} + +/** + * + */ +int PushRegistryHandler::readIntAsBooleanArg(CommsMessage& aMsg,const std::string& aMsgName) +{ + int retValue = readIntArg(aMsg,aMsgName); + + if ((0 != retValue) && (1 != retValue)) + { + std::string errTxt("Incorrect integer value in the "); + errTxt.append(aMsgName); + errTxt.append(" msg"); + ELOG1(EJavaPush,"ERROR!!! %s",errTxt.c_str()); + throw PushException(INCORRECT_COMMS_MSG,errTxt,__FILE__,__FUNCTION__,__LINE__); + } + return retValue; +} + +/** + * + */ +int PushRegistryHandler::readIntArg(CommsMessage& aMsg,const std::string& aMsgName) +{ + int retValue = -1; + if (!(aMsg >> retValue)) + { + std::string errTxt("Cannot read int from "); + errTxt.append(aMsgName); + errTxt.append(" msg"); + ELOG1(EJavaPush,"ERROR!!! %s",errTxt.c_str()); + throw PushException(INCORRECT_COMMS_MSG,errTxt,__FILE__,__FUNCTION__,__LINE__); + } + return retValue; +} + +/** + * + */ +long long PushRegistryHandler::readLongLongArg(CommsMessage& aMsg,const std::string& aMsgName) +{ + long long retValue = -1; + if (!(aMsg >> retValue)) + { + std::string errTxt("Cannot read long long value from "); + errTxt.append(aMsgName); + errTxt.append(" msg"); + ELOG1(EJavaPush,"ERROR!!! %s",errTxt.c_str()); + throw PushException(INCORRECT_COMMS_MSG,errTxt,__FILE__,__FUNCTION__,__LINE__); + } + return retValue; +} + +