From 5ece3928a9fdf2ca10be2d3c73acdbafc76cfa0a Mon Sep 17 00:00:00 2001 From: Kyeonghun Lee Date: Thu, 22 Sep 2016 20:31:44 +0900 Subject: [PATCH] resolve TSAM-7570: add new API - msg_reg_thread_change_callback() Change-Id: Id21dde9a3a48f86bf807af6af18b912fc15e8c8f Signed-off-by: Kyeonghun Lee --- framework/plugin-manager/MsgPluginManager.cpp | 50 +++++++++ framework/storage-handler/MsgStorageMessage.cpp | 28 ++++- .../transaction-manager/MsgCmdHandlerTransport.cpp | 53 +++++++++ framework/transaction-manager/MsgTransManager.cpp | 125 +++++++++++++++++++++ include/common/MsgCmdTypes.h | 5 + include/common/MsgPluginInterface.h | 2 + include/framework/MsgCmdHandler.h | 2 + include/framework/MsgTransManager.h | 3 + include/mapi/msg_storage.h | 28 +++++ include/mapi/msg_storage_types.h | 10 ++ include/proxy/MsgHandle.h | 1 + include/proxy/MsgProxyListener.h | 11 ++ include/utils/MsgUtilFunction.h | 2 + mapi/msg_storage.cpp | 24 ++++ plugin/sms_plugin/SmsPluginEventHandler.cpp | 9 ++ plugin/sms_plugin/SmsPluginStorage.cpp | 11 ++ plugin/sms_plugin/include/SmsPluginEventHandler.h | 1 + proxy/MsgHandleControl.cpp | 1 + proxy/MsgHandleStorage.cpp | 59 ++++++++++ proxy/MsgProxyListener.cpp | 52 +++++++++ utils/MsgDebug.cpp | 8 ++ utils/MsgUtilFunction.cpp | 19 ++++ 22 files changed, 502 insertions(+), 2 deletions(-) diff --git a/framework/plugin-manager/MsgPluginManager.cpp b/framework/plugin-manager/MsgPluginManager.cpp index 9fd26ef..cea023e 100755 --- a/framework/plugin-manager/MsgPluginManager.cpp +++ b/framework/plugin-manager/MsgPluginManager.cpp @@ -131,6 +131,55 @@ void MsgStorageChangeListener(msg_storage_change_type_t storageChangeType, msg_i } +void MsgThreadChangeListener(msg_storage_change_type_t storageChangeType, msg_thread_id_t threadId) +{ + MSG_BEGIN(); + + MSG_DEBUG("StorageChangeType : [%d], thread ID : [%d]", storageChangeType, threadId); + + /* establish connection to msgfw daemon */ + MsgIpcClientSocket client; + try { + client.connect(MSG_SOCKET_PATH); + } catch (MsgException& e) { + MSG_FATAL("%s", e.what()); + return; + } + + /* composing command */ + int cmdSize = sizeof(MSG_CMD_S) + sizeof(msg_thread_id_t); + + char cmdBuf[cmdSize]; + bzero(cmdBuf, cmdSize); + + MSG_CMD_S* pCmd = (MSG_CMD_S*)cmdBuf; + + /* Set Command Parameters */ + pCmd->cmdType = MSG_CMD_PLG_THREAD_CHANGE_IND; + + memset(pCmd->cmdCookie, 0x00, MAX_COOKIE_LEN); + + memcpy((void*)((char*)pCmd+sizeof(MSG_CMD_TYPE_T)+MAX_COOKIE_LEN), &threadId, sizeof(msg_thread_id_t)); + memcpy((void*)((char*)pCmd+sizeof(MSG_CMD_TYPE_T)+MAX_COOKIE_LEN+sizeof(msg_thread_id_t)), &storageChangeType, sizeof(msg_storage_change_type_t)); + + /* Send Command to Transaction Manager */ + client.write(cmdBuf, cmdSize); + + /* Receive result from Transaction Manager */ + MSG_DEBUG("Waiting result for STORAGE CHANGE"); + + char *temp = NULL; + unique_ptr wrap(&temp, unique_ptr_deleter); + unsigned int len; + client.read(&temp, &len); + + /* close connection to msgfw daemon */ + client.close(); + + MSG_END(); +} + + msg_error_t MsgIncomingMessageListener(MSG_MESSAGE_INFO_S *pMsg) { MSG_BEGIN(); @@ -862,6 +911,7 @@ MsgPlugin::MsgPlugin(MSG_MAIN_TYPE_T mainType, const char *libPath): mSupportedM MSG_PLUGIN_LISTENER_S fwListener = {0}; fwListener.pfSentStatusCb = &MsgSentStatusListener; fwListener.pfStorageChangeCb = &MsgStorageChangeListener; + fwListener.pfThreadChangeCb = &MsgThreadChangeListener; fwListener.pfMsgIncomingCb = &MsgIncomingMessageListener; fwListener.pfInitSimBySatCb = &MsgInitSimBySatListener; fwListener.pfSyncMLMsgIncomingCb = &MsgIncomingSyncMLMessageListener; diff --git a/framework/storage-handler/MsgStorageMessage.cpp b/framework/storage-handler/MsgStorageMessage.cpp index de136bf..e5b6dbe 100755 --- a/framework/storage-handler/MsgStorageMessage.cpp +++ b/framework/storage-handler/MsgStorageMessage.cpp @@ -1013,6 +1013,10 @@ msg_error_t MsgStoDeleteMessage(msg_message_id_t msgId, bool bCheckIndication) } dbHandle->endTrans(true); + /* Update Thread Callback */ + if (bCheckIndication == true && MsgExistConversation(dbHandle, convId) == true) + MsgTransactionManager::instance()->broadcastThreadChangeCB(MSG_SUCCESS, MSG_STORAGE_CHANGE_UPDATE, convId); + if (msgType.mainType == MSG_SMS_TYPE && folderId == MSG_INBOX_ID) { msgType.classType = MSG_CLASS_NONE; @@ -1039,7 +1043,7 @@ msg_error_t MsgStoDeleteAllMessageInFolder(msg_folder_id_t folderId, bool bOnlyD char sqlQuery[MAX_QUERY_LEN+1]; - queue threadList; + queue threadList, threadList2; #ifdef FEATURE_SMS_CDMA const char *tableList[] = {MSGFW_PUSH_MSG_TABLE_NAME, MSGFW_CB_MSG_TABLE_NAME, @@ -1081,6 +1085,7 @@ msg_error_t MsgStoDeleteAllMessageInFolder(msg_folder_id_t folderId, bool bOnlyD for (int i = 1; i <= rowCnt; i++) { MSG_DEBUG("thread ID : %d", dbHandle->getColumnToInt(i)); threadList.push((msg_thread_id_t)dbHandle->getColumnToInt(i)); + threadList2.push((msg_thread_id_t)dbHandle->getColumnToInt(i)); } dbHandle->freeTable(); @@ -1306,6 +1311,15 @@ msg_error_t MsgStoDeleteAllMessageInFolder(msg_folder_id_t folderId, bool bOnlyD dbHandle->endTrans(true); + /* Update Thread Callback */ + while (!threadList2.empty()) { + msg_thread_id_t cur_thread_id = threadList2.front(); + if (MsgExistConversation(dbHandle, cur_thread_id) == true) + MsgTransactionManager::instance()->broadcastThreadChangeCB(MSG_SUCCESS, MSG_STORAGE_CHANGE_UPDATE, cur_thread_id); + + threadList2.pop(); + } + /* Set pMsgIdList */ if (pMsgIdList != NULL && pToDeleteMsgIdList->nCount > 0) { pMsgIdList->nCount = pToDeleteMsgIdList->nCount; @@ -1368,7 +1382,7 @@ msg_error_t MsgStoDeleteMessageByList(msg_id_list_s *pMsgIdList) char sqlQuery[MAX_QUERY_LEN+1]; - queue threadList1, threadList2; + queue threadList1, threadList2, threadList3; #ifdef FEATURE_SMS_CDMA const char *tableList[] = {MMS_PLUGIN_MESSAGE_TABLE_NAME, MSGFW_MMS_PREVIEW_TABLE_NAME, @@ -1451,6 +1465,7 @@ msg_error_t MsgStoDeleteMessageByList(msg_id_list_s *pMsgIdList) MSG_DEBUG("thread ID : %d", dbHandle->getColumnToInt(i)); threadList1.push((msg_thread_id_t)dbHandle->getColumnToInt(i)); threadList2.push((msg_thread_id_t)dbHandle->getColumnToInt(i)); + threadList3.push((msg_thread_id_t)dbHandle->getColumnToInt(i)); } dbHandle->freeTable(); @@ -1653,6 +1668,15 @@ msg_error_t MsgStoDeleteMessageByList(msg_id_list_s *pMsgIdList) return err; } + /* Update Thread Callback */ + while (!threadList3.empty()) { + msg_thread_id_t cur_thread_id = threadList3.front(); + if (MsgExistConversation(dbHandle, cur_thread_id) == true) + MsgTransactionManager::instance()->broadcastThreadChangeCB(MSG_SUCCESS, MSG_STORAGE_CHANGE_UPDATE, cur_thread_id); + + threadList3.pop(); + } + if (g_idle_add(resetNotification, NULL) == 0) { MSG_DEBUG("resetNotification() Error"); } diff --git a/framework/transaction-manager/MsgCmdHandlerTransport.cpp b/framework/transaction-manager/MsgCmdHandlerTransport.cpp index c4382cb..5448e2a 100755 --- a/framework/transaction-manager/MsgCmdHandlerTransport.cpp +++ b/framework/transaction-manager/MsgCmdHandlerTransport.cpp @@ -369,6 +369,29 @@ int MsgRegStorageChangeCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent) } +int MsgRegThreadChangeCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent) +{ + /* input check */ + if (!pCmd || !ppEvent) { + MSG_DEBUG("pCmd or ppEvent is null"); + return 0; + } + + /* Get Message Request */ + int listenerFd = 0; + memcpy(&listenerFd, (void*)((char*)pCmd+sizeof(MSG_CMD_TYPE_T)+MAX_COOKIE_LEN), sizeof(int)); + MSG_DEBUG("Registering storage change CB for %d", listenerFd); + + /* storing dst fd in list */ + MsgTransactionManager::instance()->setThreadChangeCB(listenerFd); + + /* Make Event Data */ + int eventSize = MsgMakeEvent(NULL, 0, MSG_EVENT_REG_THREAD_CHANGE_CB, MsgException::SUCCESS, (void**)ppEvent); + + return eventSize; +} + + int MsgRegIncomingReportMsgCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent) { /* input check */ @@ -1001,6 +1024,36 @@ int MsgStorageChangeHandler(const MSG_CMD_S *pCmd, char **ppEvent) return eventSize; } +int MsgThreadChangeHandler(const MSG_CMD_S *pCmd, char **ppEvent) +{ + /* input check */ + if (!pCmd || !ppEvent) { + MSG_DEBUG("pCmd or ppEvent is null"); + return 0; + } + + msg_storage_change_type_t storageChangeType; + msg_thread_id_t threadId; + + memcpy(&threadId, (void*)((char*)pCmd+sizeof(MSG_CMD_TYPE_T)+MAX_COOKIE_LEN), sizeof(msg_thread_id_t)); + memcpy(&storageChangeType, (void*)((char*)pCmd+sizeof(MSG_CMD_TYPE_T)+MAX_COOKIE_LEN+sizeof(msg_thread_id_t)), sizeof(msg_storage_change_type_t)); + + char* encodedData = NULL; + unique_ptr buf(&encodedData, unique_ptr_deleter); + + int eventSize = 0; + + MSG_DEBUG("storageChangeType : [%d], thread Id : [%d]", storageChangeType, threadId); + + /* broadcast to listener threads, here */ + MsgTransactionManager::instance()->broadcastThreadChangeCB(MSG_SUCCESS, storageChangeType, threadId); + + /* Make Event Data to Client */ + eventSize = MsgMakeEvent(NULL, 0, MSG_EVENT_PLG_THREAD_CHANGE_IND, MSG_SUCCESS, (void**)ppEvent); + + return eventSize; +} + int MsgResendMessageHandler(const MSG_CMD_S *pCmd, char **ppEvent) { msg_error_t err = MSG_SUCCESS; diff --git a/framework/transaction-manager/MsgTransManager.cpp b/framework/transaction-manager/MsgTransManager.cpp index d59bcd6..56d0a7f 100755 --- a/framework/transaction-manager/MsgTransManager.cpp +++ b/framework/transaction-manager/MsgTransManager.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,8 @@ #include "MsgContact.h" #include "MsgIpcSocket.h" #include "MsgGconfWrapper.h" +#include "MsgSqliteWrapper.h" +#include "MsgUtilStorage.h" #include "MsgUtilFunction.h" #include "MsgUtilFile.h" #include "MsgLbs.h" @@ -41,6 +44,8 @@ #define MSG_CHECK_PRIVILEGE +std::list cur_conv_list; + void MsgMakeErrorEvent(MSG_CMD_TYPE_T cmdType, msg_error_t errType, int *pEventSize, char **ppEvent) { if (*ppEvent) delete [] *ppEvent; @@ -54,6 +59,29 @@ void MsgMakeErrorEvent(MSG_CMD_TYPE_T cmdType, msg_error_t errType, int *pEventS pMsgEvent->result = errType; } +void initConversationList() +{ + MsgDbHandler *dbHandle = getDbHandle(); + + msg_error_t err = MSG_SUCCESS; + int rowCnt = 0; + + char sqlQuery[MAX_QUERY_LEN+1] = {0}; + snprintf(sqlQuery, MAX_QUERY_LEN, "SELECT CONV_ID FROM %s;", MSGFW_CONVERSATION_TABLE_NAME); + + err = dbHandle->getTable(sqlQuery, &rowCnt, NULL); + if (err != MSG_SUCCESS) { + MSG_DEBUG("getTable failed [%d]", err); + dbHandle->freeTable(); + return; + } + + for (int i = 0; i < rowCnt; i++) + cur_conv_list.push_back((msg_thread_id_t)dbHandle->getColumnToInt(i+1)); + + dbHandle->freeTable(); +} + /*================================================================================================== IMPLEMENTATION OF MsgTransactionManager - Member Functions ==================================================================================================*/ @@ -75,6 +103,8 @@ MsgTransactionManager::MsgTransactionManager() : running(false), mx(), mxQ(), cv handlerMap.clear(); + initConversationList(); + /* Fill in mMsgHandlers, as given in the below. */ handlerMap[MSG_CMD_ADD_MSG] = &MsgAddMessageHandler; handlerMap[MSG_CMD_ADD_SYNCML_MSG] = &MsgAddSyncMLMessageHandler; @@ -105,6 +135,7 @@ MsgTransactionManager::MsgTransactionManager() : running(false), mx(), mxQ(), cv handlerMap[MSG_CMD_REG_SENT_STATUS_CB] = &MsgRegSentStatusCallbackHandler; handlerMap[MSG_CMD_REG_STORAGE_CHANGE_CB] = &MsgRegStorageChangeCallbackHandler; + handlerMap[MSG_CMD_REG_THREAD_CHANGE_CB] = &MsgRegThreadChangeCallbackHandler; handlerMap[MSG_CMD_REG_INCOMING_MSG_CB] = &MsgRegIncomingMsgCallbackHandler; handlerMap[MSG_CMD_REG_INCOMING_MMS_CONF_MSG_CB] = &MsgRegIncomingMMSConfMsgCallbackHandler; handlerMap[MSG_CMD_REG_INCOMING_SYNCML_MSG_CB] = &MsgRegIncomingSyncMLMsgCallbackHandler; @@ -642,6 +673,7 @@ bool MsgTransactionManager::checkPrivilege(int fd, MSG_CMD_TYPE_T CmdType) case MSG_CMD_GET_MEMSIZE: case MSG_CMD_BACKUP_MESSAGE: case MSG_CMD_REG_STORAGE_CHANGE_CB: + case MSG_CMD_REG_THREAD_CHANGE_CB: case MSG_CMD_GET_REPORT_STATUS: case MSG_CMD_GET_THREAD_ID_BY_ADDRESS: case MSG_CMD_GET_THREAD_INFO: @@ -934,6 +966,17 @@ void MsgTransactionManager::setStorageChangeCB(int listenerFd) } +void MsgTransactionManager::setThreadChangeCB(int listenerFd) +{ + if (listenerFd <= 0) + THROW(MsgException::INVALID_PARAM, "InParam Error: listenerFd %d", listenerFd); + + MsgMutexLocker lock(mx); + + threadChangeFdMap[listenerFd] = true; +} + + void MsgTransactionManager::setReportMsgCB(int listenerFd) { if (listenerFd <= 0) @@ -1176,6 +1219,15 @@ void MsgTransactionManager::broadcastSyncMLMsgOperationCB(const msg_error_t err, } +bool compare_func(msg_thread_id_t const &a, msg_thread_id_t const &b) +{ + if (a == b) + return true; + + return false; +} + + void MsgTransactionManager::broadcastStorageChangeCB(const msg_error_t err, const msg_storage_change_type_t storageChangeType, const msg_id_list_s *pMsgIdList) { MSG_BEGIN(); @@ -1209,6 +1261,79 @@ void MsgTransactionManager::broadcastStorageChangeCB(const msg_error_t err, cons write(it->first, pEventData, eventSize); } + MsgDbHandler *dbHandle = getDbHandle(); + MsgSimpleQ updatedConvQ; + + if (storageChangeType == MSG_STORAGE_CHANGE_INSERT) { + for (int i = 0; i < pMsgIdList->nCount; i++) { + msg_thread_id_t conv_id = MsgGetThreadId(dbHandle, pMsgIdList->msgIdList[i]); + bool found = (std::find(cur_conv_list.begin(), cur_conv_list.end(), conv_id) != cur_conv_list.end()); + + if (found == false) { + cur_conv_list.push_back(conv_id); + updatedConvQ.push_back(conv_id); + broadcastThreadChangeCB(MSG_SUCCESS, MSG_STORAGE_CHANGE_INSERT, conv_id); + } else { + if (updatedConvQ.checkExist(conv_id, compare_func) == false) { + broadcastThreadChangeCB(MSG_SUCCESS, MSG_STORAGE_CHANGE_UPDATE, conv_id); + updatedConvQ.push_back(conv_id); + } + } + } + } else if (storageChangeType == MSG_STORAGE_CHANGE_UPDATE) { + for (int i = 0; i < pMsgIdList->nCount; i++) { + msg_thread_id_t conv_id = MsgGetThreadId(dbHandle, pMsgIdList->msgIdList[i]); + if (updatedConvQ.checkExist(conv_id, compare_func) == false) { + broadcastThreadChangeCB(MSG_SUCCESS, MSG_STORAGE_CHANGE_UPDATE, conv_id); + updatedConvQ.push_back(conv_id); + } + } + } else if (storageChangeType == MSG_STORAGE_CHANGE_DELETE) { + std::list::iterator it = cur_conv_list.begin(); + for (; it != cur_conv_list.end(); ) { + if (MsgExistConversation(dbHandle, *it) == false) { + broadcastThreadChangeCB(MSG_SUCCESS, MSG_STORAGE_CHANGE_DELETE, *it); + it = cur_conv_list.erase(it); + } else{ + it++; + } + } + } + + updatedConvQ.clear(); + + MSG_END(); +} + + +void MsgTransactionManager::broadcastThreadChangeCB(const msg_error_t err, const msg_storage_change_type_t storageChangeType, const msg_thread_id_t threadId) +{ + MSG_BEGIN(); + + MSG_DEBUG("storageChangeType [%d], threadId [%d]", storageChangeType, threadId); + + int dataSize = 0; + + char* pEventData = NULL; + unique_ptr eventBuf(&pEventData, unique_ptr_deleter); + + char* encodedData = NULL; + unique_ptr buf(&encodedData, unique_ptr_deleter); + + /* Encoding Thread Change Data */ + dataSize = MsgEncodeThreadChangeData(storageChangeType, threadId, &encodedData); + + int eventSize = MsgMakeEvent(encodedData, dataSize, MSG_EVENT_PLG_THREAD_CHANGE_IND, err, (void**)(&pEventData)); + + MsgMutexLocker lock(mx); + + fd_map::iterator it = threadChangeFdMap.begin(); + + for (; it != threadChangeFdMap.end(); it++) { + MSG_DEBUG("Send Thread Change Callback to listener %d", it->first); + write(it->first, pEventData, eventSize); + } + MSG_END(); } diff --git a/include/common/MsgCmdTypes.h b/include/common/MsgCmdTypes.h index fed00ec..fd21d0c 100755 --- a/include/common/MsgCmdTypes.h +++ b/include/common/MsgCmdTypes.h @@ -166,6 +166,9 @@ enum _MSG_CMD_TYPE_E { #endif MSG_CMD_CHECK_PERMISSION, + MSG_CMD_REG_THREAD_CHANGE_CB, + MSG_CMD_PLG_THREAD_CHANGE_IND, + /* end of MSG_CMD; new CMD should be defined before MSG_CMD_NUM */ MSG_CMD_NUM }; @@ -277,6 +280,8 @@ enum _MSG_EVENT_TYPE_E { MSG_EVENT_PLG_CHECK_UNIQUENESS, #endif MSG_EVENT_CHECK_PERMISSION, + MSG_EVENT_REG_THREAD_CHANGE_CB, + MSG_EVENT_PLG_THREAD_CHANGE_IND, /* Enums that does not match _MSG_CMD_TYPE_E */ MSG_EVENT_PLG_REPORT_MSG_INCOMING_IND, diff --git a/include/common/MsgPluginInterface.h b/include/common/MsgPluginInterface.h index 62ab9fb..b144ca0 100755 --- a/include/common/MsgPluginInterface.h +++ b/include/common/MsgPluginInterface.h @@ -1052,6 +1052,7 @@ typedef msg_error_t (*MsgPlgGetDefaultNetworkSimId) (int *simId); /* framework defined callbacks. */ typedef void (*MsgPlgOnSentStatus)(MSG_SENT_STATUS_S *pSentStatus); typedef void (*MsgPlgOnStorageChange)(msg_storage_change_type_t storageChangeType, msg_id_list_s *pMsgIdList); +typedef void (*MsgPlgOnThreadChange)(msg_storage_change_type_t storageChangeType, msg_thread_id_t threadId); typedef msg_error_t (*MsgPlgOnMsgIncoming)(MSG_MESSAGE_INFO_S *pMsgInfo); typedef msg_error_t (*MsgPlgOnInitSimBySat)(void); typedef msg_error_t (*MsgPlgOnSyncMLMsgIncoming)(MSG_SYNCML_MESSAGE_DATA_S *pSyncMLData); @@ -1072,6 +1073,7 @@ typedef msg_error_t (*MsgPlgOnInitImsi)(int sim_idx); struct _MSG_PLUGIN_LISTENER_S { MsgPlgOnSentStatus pfSentStatusCb; /** The function pointer of sent status callback. */ MsgPlgOnStorageChange pfStorageChangeCb; /** The function pointer of storage change callback. */ + MsgPlgOnThreadChange pfThreadChangeCb; /** The function pointer of thread change callback. */ MsgPlgOnMsgIncoming pfMsgIncomingCb; /** The function pointer of receive message callback. */ MsgPlgOnInitSimBySat pfInitSimBySatCb; /** The function pointer of init SIM callback. */ MsgPlgOnSyncMLMsgIncoming pfSyncMLMsgIncomingCb; /** The function pointer of receive syncML message callback. */ diff --git a/include/framework/MsgCmdHandler.h b/include/framework/MsgCmdHandler.h index f5b9536..f74a208 100755 --- a/include/framework/MsgCmdHandler.h +++ b/include/framework/MsgCmdHandler.h @@ -78,7 +78,9 @@ int MsgRegIncomingSyncMLMsgCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent int MsgRegIncomingLBSMsgCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent); int MsgRegSyncMLMsgOperationCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent); int MsgRegStorageChangeCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent); +int MsgRegThreadChangeCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent); int MsgStorageChangeHandler(const MSG_CMD_S *pCmd, char **ppEvent); +int MsgThreadChangeHandler(const MSG_CMD_S *pCmd, char **ppEvent); int MsgRegIncomingReportMsgCallbackHandler(const MSG_CMD_S *pCmd, char **ppEvent); int MsgSentStatusHandler(const MSG_CMD_S *pCmd, char **ppEvent); diff --git a/include/framework/MsgTransManager.h b/include/framework/MsgTransManager.h index 7f8413f..32761f9 100755 --- a/include/framework/MsgTransManager.h +++ b/include/framework/MsgTransManager.h @@ -80,6 +80,7 @@ public: void setJavaMMSList(MSG_CMD_REG_INCOMING_JAVAMMS_TRID_S *pTrId); void setSyncMLMsgOperationCB(MSG_CMD_REG_SYNCML_MSG_OPERATION_CB_S *pCbinfo); void setStorageChangeCB(int listenerFd); + void setThreadChangeCB(int listenerFd); void setReportMsgCB(int listenerFd); javamms_list &getJavaMMSList(); @@ -92,6 +93,7 @@ public: void broadcastLBSMsgCB(const msg_error_t err, const MSG_LBS_MESSAGE_DATA_S *lbsData); void broadcastSyncMLMsgOperationCB(const msg_error_t err, const int msgId, const int extId); void broadcastStorageChangeCB(const msg_error_t err, const msg_storage_change_type_t storageChangeType, const msg_id_list_s *pMsgIdList); + void broadcastThreadChangeCB(const msg_error_t err, const msg_storage_change_type_t storageChangeType, const msg_thread_id_t threadId); void broadcastReportMsgCB(const msg_error_t err, const msg_report_type_t reportMsgType, const MSG_MESSAGE_INFO_S *pMsgInfo); bool initCynara(); @@ -125,6 +127,7 @@ private: syncmlop_list operationSyncMLMsgCBList; fd_map storageChangeFdMap; + fd_map threadChangeFdMap; fd_map reportMsgCBFdMap; MsgMutex mx; /* mutex for shared resources like callback listeners */ diff --git a/include/mapi/msg_storage.h b/include/mapi/msg_storage.h index feeb2d2..4fb9263 100755 --- a/include/mapi/msg_storage.h +++ b/include/mapi/msg_storage.h @@ -845,6 +845,34 @@ int msg_reg_storage_change_callback(msg_handle_t handle, msg_storage_change_cb c /** + * @brief Registers a callback function about the change of thread status to Message handle. + * @details This API is used to register a callback function about the change of thread status "msg_thread_change_cb" to Message handle. + * + * @since_tizen 3.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/message.read + * + * @remarks This function MUST be called after Message handle is opened. + * + * @param[in] handle The Message handle + * @param[in] cb The function to be called + * @param[in] user_param A pointer to user data + * + * @return @c 0 on success, + * otherwise a negative error value + * + * @retval MSG_SUCCESS Success in operation + * @retval MSG_ERR_INVALID_PARAMETER Parameter is invalid + * @retval MSG_ERR_MSGHANDLE_NOT_CONNECTED Message handle is not connected + * @retval MSG_ERR_MEMORY_ERROR Memory is error + * @retval MSG_ERR_PERMISSION_DENIED The application does not have the privilege to call this method + * @retval MSG_ERR_NOT_SUPPORTED Not supported + */ + +int msg_reg_thread_change_callback(msg_handle_t handle, msg_thread_change_cb cb, void *user_param); + + +/** * @brief Gets the report status information of message. * * @since_tizen 2.3 diff --git a/include/mapi/msg_storage_types.h b/include/mapi/msg_storage_types.h index 8a740df..f3e59bd 100755 --- a/include/mapi/msg_storage_types.h +++ b/include/mapi/msg_storage_types.h @@ -95,6 +95,16 @@ typedef unsigned char msg_storage_change_type_t; typedef void (*msg_storage_change_cb)(msg_handle_t handle, msg_storage_change_type_t storageChangeType, msg_id_list_s *pMsgIdList, void *user_param); +/** @brief Called when the threads of message framework is changed. + * Applications SHOULD implement this callback function and register it into Message handle. + * For how to register this callback function, please refer to msg_reg_thread_change_callback(). + * The callback function runs in the application process, not in the framework process. + * @param[in] handle The Message handle. + * @param[in] user_param A pointer to user data + */ +typedef void (*msg_thread_change_cb)(msg_handle_t handle, msg_storage_change_type_t storageChangeType, msg_thread_id_t threadId, void *user_param); + + /*================================================================================================== ENUMS ==================================================================================================*/ diff --git a/include/proxy/MsgHandle.h b/include/proxy/MsgHandle.h index 816013e..f3acaae 100755 --- a/include/proxy/MsgHandle.h +++ b/include/proxy/MsgHandle.h @@ -135,6 +135,7 @@ public: msg_error_t getRejectMsgList(const char *pNumber, msg_struct_list_s *pRejectMsgList); msg_error_t regStorageChangeCallback(msg_storage_change_cb onStorageChange, void *pUserParam); + msg_error_t regThreadChangeCallback(msg_thread_change_cb onThreadChange, void *pUserParam); msg_error_t getReportStatus(msg_message_id_t msg_id, msg_struct_list_s *report_list); msg_error_t getThreadIdByAddress(msg_struct_list_s *pAddrList, msg_thread_id_t *pThreadId); msg_error_t getThreadIdByAddress(msg_list_handle_t msg_address_list, msg_thread_id_t *pThreadId); diff --git a/include/proxy/MsgProxyListener.h b/include/proxy/MsgProxyListener.h index 99f2141..6cf9dc8 100755 --- a/include/proxy/MsgProxyListener.h +++ b/include/proxy/MsgProxyListener.h @@ -113,6 +113,14 @@ typedef struct { typedef struct { MsgHandle* hAddr; int fd; + msg_thread_change_cb pfThreadChangeCB; + void* userParam; +} MSG_THREAD_CHANGE_CB_ITEM_S; + + +typedef struct { + MsgHandle* hAddr; + int fd; msg_report_msg_incoming_cb pfReportMsgIncomingCB; void* userParam; } MSG_REPORT_INCOMING_CB_ITEM_S; @@ -127,6 +135,7 @@ typedef std::list MsgNewSyncMLMessageCBList; typedef std::list MsgNewLBSMessageCBList; typedef std::list MsgOperationSyncMLMessageCBList; typedef std::list MsgStorageChangeCBList; +typedef std::list MsgThreadChangeCBList; typedef std::list MsgReportMessageCBList; typedef std::set handle_set; @@ -150,6 +159,7 @@ public: bool regLBSMessageIncomingEventCB(MsgHandle* pMsgHandle, int fd, msg_lbs_msg_incoming_cb pfNewLBSMsgIncoming, void *pUserParam); bool regSyncMLMessageOperationEventCB(MsgHandle* pMsgHandle, int fd, msg_syncml_msg_operation_cb pfSyncMLMessageOperation, void *pUserParam); bool regStorageChangeEventCB(MsgHandle* pMsgHandle, int fd, msg_storage_change_cb pfStorageChangeOperation, void *pUserParam); + bool regThreadChangeEventCB(MsgHandle* pMsgHandle, int fd, msg_thread_change_cb pfThreadChangeOperation, void *pUserParam); bool regReportMsgIncomingCB(MsgHandle* pMsgHandle, int fd, msg_report_msg_incoming_cb pfReportMessage, void *pUserParam); void clearListOfClosedHandle(MsgHandle* pMsgHandle); @@ -192,6 +202,7 @@ private: MsgNewLBSMessageCBList newLBSMessageCBList; MsgOperationSyncMLMessageCBList operationSyncMLMessageCBList; MsgStorageChangeCBList storageChangeCBList; + MsgThreadChangeCBList threadChangeCBList; MsgReportMessageCBList reportMessageCBList; GIOChannel *channel; diff --git a/include/utils/MsgUtilFunction.h b/include/utils/MsgUtilFunction.h index f5656f1..82ded6e 100755 --- a/include/utils/MsgUtilFunction.h +++ b/include/utils/MsgUtilFunction.h @@ -84,6 +84,8 @@ int MsgEncodeSyncMLOperationData(int msgId, int extId, char **ppDest); int MsgEncodeStorageChangeData(const msg_storage_change_type_t storageChangeType, const msg_id_list_s *pMsgIdList, char **ppDest); +int MsgEncodeThreadChangeData(const msg_storage_change_type_t storageChangeType, const msg_thread_id_t threadId, char **ppDest); + int MsgEncodeReportMsgData(const msg_report_type_t msgReportType, const MSG_MESSAGE_INFO_S *pMsgInfo, char **ppDest); int MsgEncodeReportStatus(MSG_REPORT_STATUS_INFO_S* pReportStatus, int count, char **ppDest); diff --git a/mapi/msg_storage.cpp b/mapi/msg_storage.cpp index 5c509e4..8710602 100755 --- a/mapi/msg_storage.cpp +++ b/mapi/msg_storage.cpp @@ -951,6 +951,30 @@ EXPORT_API int msg_reg_storage_change_callback(msg_handle_t handle, msg_storage_ return err; } +EXPORT_API int msg_reg_thread_change_callback(msg_handle_t handle, msg_thread_change_cb cb, void *user_param) +{ + CHECK_MSG_SUPPORTED(MSG_TELEPHONY_SMS_FEATURE); + msg_error_t err = MSG_SUCCESS; + + if (handle == NULL || cb == NULL) + return MSG_ERR_INVALID_PARAMETER; + + MsgHandle* pHandle = (MsgHandle*)handle; + + try { + err = pHandle->regThreadChangeCallback(cb, user_param); + } catch (MsgException& e) { + MSG_FATAL("%s", e.what()); + if (e.errorCode() == MsgException::SERVER_READY_ERROR) + return MSG_ERR_PERMISSION_DENIED; + else + return MSG_ERR_CALLBACK_ERROR; + } + + return err; + +} + EXPORT_API int msg_get_report_status(msg_handle_t handle, msg_message_id_t msg_id, msg_struct_list_s *report_list) { CHECK_MSG_SUPPORTED(MSG_TELEPHONY_SMS_FEATURE); diff --git a/plugin/sms_plugin/SmsPluginEventHandler.cpp b/plugin/sms_plugin/SmsPluginEventHandler.cpp index 7685911..68fdf01 100755 --- a/plugin/sms_plugin/SmsPluginEventHandler.cpp +++ b/plugin/sms_plugin/SmsPluginEventHandler.cpp @@ -509,6 +509,15 @@ msg_error_t SmsPluginEventHandler::callbackStorageChange(msg_storage_change_type } +msg_error_t SmsPluginEventHandler::callbackThreadChange(msg_storage_change_type_t storageChangeType, msg_thread_id_t threadId) +{ + /* Callback to MSG FW */ + listener.pfThreadChangeCb(storageChangeType, threadId); + + return MSG_SUCCESS; +} + + void SmsPluginEventHandler::convertTpduToMsginfo(SMS_TPDU_S *pTpdu, MSG_MESSAGE_INFO_S *msgInfo) { switch (pTpdu->tpduType) { diff --git a/plugin/sms_plugin/SmsPluginStorage.cpp b/plugin/sms_plugin/SmsPluginStorage.cpp index 3b3f215..35af834 100755 --- a/plugin/sms_plugin/SmsPluginStorage.cpp +++ b/plugin/sms_plugin/SmsPluginStorage.cpp @@ -27,6 +27,7 @@ #include "MsgNotificationWrapper.h" #include "SmsPluginMain.h" #include "SmsPluginSimMsg.h" +#include "SmsPluginEventHandler.h" #include "SmsPluginStorage.h" @@ -636,6 +637,16 @@ msg_error_t SmsPluginStorage::deleteSmsMessage(msg_message_id_t msgId) dbHandle->endTrans(true); + memset(sqlQuery, 0x00, sizeof(sqlQuery)); + snprintf(sqlQuery, sizeof(sqlQuery), "SELECT CONV_ID FROM %s WHERE CONV_ID = %d;", MSGFW_CONVERSATION_TABLE_NAME, convId); + if (dbHandle->prepareQuery(sqlQuery) != MSG_SUCCESS) + return MSG_ERR_DB_PREPARE; + + if (dbHandle->stepQuery() == MSG_ERR_DB_ROW) + SmsPluginEventHandler::instance()->callbackThreadChange(MSG_STORAGE_CHANGE_UPDATE, convId); + + dbHandle->finalizeQuery(); + signed char folder_id = (signed char)folderId; if (folder_id == MSG_INBOX_ID) { msgType.classType = MSG_CLASS_NONE; diff --git a/plugin/sms_plugin/include/SmsPluginEventHandler.h b/plugin/sms_plugin/include/SmsPluginEventHandler.h index 035f33a..c7c1f0c 100755 --- a/plugin/sms_plugin/include/SmsPluginEventHandler.h +++ b/plugin/sms_plugin/include/SmsPluginEventHandler.h @@ -47,6 +47,7 @@ public: msg_error_t callbackCBMsgIncoming(MSG_CB_MSG_S *pCbMsg, MSG_MESSAGE_INFO_S *pMsgInfo); msg_error_t callbackInitSimBySat(); msg_error_t callbackStorageChange(msg_storage_change_type_t storageChangeType, MSG_MESSAGE_INFO_S *pMsgInfo); + msg_error_t callbackThreadChange(msg_storage_change_type_t storageChangeType, msg_thread_id_t threadId); msg_error_t handleSimMsg(MSG_MESSAGE_INFO_S *pMsgInfo, int *simIdList, msg_message_id_t *retMsgId, int listSize); msg_error_t updateIMSI(int sim_idx); void handleSimMemoryFull(int simIndex); diff --git a/proxy/MsgHandleControl.cpp b/proxy/MsgHandleControl.cpp index e4a9f5c..8220910 100755 --- a/proxy/MsgHandleControl.cpp +++ b/proxy/MsgHandleControl.cpp @@ -616,6 +616,7 @@ bool MsgHandle::checkEventData(char *pEventData) case MSG_EVENT_PLG_INCOMING_SYNCML_MSG_IND: case MSG_EVENT_PLG_INCOMING_LBS_MSG_IND: case MSG_EVENT_PLG_STORAGE_CHANGE_IND: + case MSG_EVENT_PLG_THREAD_CHANGE_IND: case MSG_EVENT_PLG_INCOMING_CB_MSG_IND: case MSG_EVENT_PLG_INCOMING_PUSH_MSG_IND: case MSG_EVENT_PLG_REPORT_MSG_INCOMING_IND: diff --git a/proxy/MsgHandleStorage.cpp b/proxy/MsgHandleStorage.cpp index bc30ecb..7e1d989 100755 --- a/proxy/MsgHandleStorage.cpp +++ b/proxy/MsgHandleStorage.cpp @@ -1409,6 +1409,65 @@ msg_error_t MsgHandle::regStorageChangeCallback(msg_storage_change_cb onStorageC } +msg_error_t MsgHandle::regThreadChangeCallback(msg_thread_change_cb onThreadChange, void *pUserParam) +{ + if (!onThreadChange) + THROW(MsgException::INVALID_PARAM, "onThreadChange is null"); + + MsgProxyListener* eventListener = MsgProxyListener::instance(); + + eventListener->start(this); + + int remoteFd = eventListener->getRemoteFd(); /* fd that is reserved to the "listener thread" by msgfw daemon */ + + if (remoteFd == -1 ) { + eventListener->stop(); + return MSG_ERR_INVALID_MSGHANDLE; + } + + if (eventListener->regThreadChangeEventCB(this, remoteFd, onThreadChange, pUserParam) == false) { + eventListener->stop(); + return MSG_ERR_INVALID_PARAMETER; + } + + /* Allocate Memory to Command Data */ + int cmdSize = sizeof(MSG_CMD_S) + sizeof(int); /* cmd type, listenerFd */ + char cmdBuf[cmdSize]; + bzero(cmdBuf, cmdSize); + MSG_CMD_S* pCmd = (MSG_CMD_S*) cmdBuf; + + /* Set Command Parameters */ + pCmd->cmdType = MSG_CMD_REG_THREAD_CHANGE_CB; + + /* Copy Cookie */ + memcpy(pCmd->cmdCookie, mCookie, MAX_COOKIE_LEN); + + MSG_DEBUG("remote fd %d", remoteFd); + + memcpy((void*)((char*)pCmd+sizeof(MSG_CMD_TYPE_T)+MAX_COOKIE_LEN), &remoteFd, sizeof(remoteFd)); + + MSG_DEBUG("reg status [%d : %s], %d", pCmd->cmdType, MsgDbgCmdStr(pCmd->cmdType), remoteFd); + + /* Send Command to Messaging FW */ + char* pEventData = NULL; + unique_ptr eventBuf(&pEventData, unique_ptr_deleter); + + write((char*)pCmd, cmdSize, &pEventData); + + /* Get Return Data */ + MSG_EVENT_S* pEvent = (MSG_EVENT_S*)pEventData; + + if (pEvent == NULL) + THROW(MsgException::INVALID_RESULT, "Event is NULL"); + + if (pEvent->eventType != MSG_EVENT_REG_THREAD_CHANGE_CB) { + THROW(MsgException::INVALID_PARAM, "Event Data Error"); + } + + return pEvent->result; +} + + msg_error_t MsgHandle::getReportStatus(msg_message_id_t msg_id, msg_struct_list_s *report_list) { /* Allocate Memory to Command Data */ diff --git a/proxy/MsgProxyListener.cpp b/proxy/MsgProxyListener.cpp index dc0493e..8d834c9 100755 --- a/proxy/MsgProxyListener.cpp +++ b/proxy/MsgProxyListener.cpp @@ -501,6 +501,33 @@ bool MsgProxyListener::regStorageChangeEventCB(MsgHandle* pMsgHandle, int fd, ms } +bool MsgProxyListener::regThreadChangeEventCB(MsgHandle* pMsgHandle, int fd, msg_thread_change_cb pfThreadChangeOperation, void *pUserParam) +{ + MsgMutexLocker lock(mx); + + std::list::iterator it = threadChangeCBList.begin(); + + for (; it != threadChangeCBList.end(); it++) { + if (it->hAddr == pMsgHandle && it->pfThreadChangeCB == pfThreadChangeOperation) { + if (it->fd == fd) { + MSG_DEBUG("msg_thread_change_cb() callback : [%p] is already registered!!!", pfThreadChangeOperation); + return false; + } else { + MSG_DEBUG("callback is registered by restarting server"); + it->fd = fd; + return true; + } + } + } + + MSG_THREAD_CHANGE_CB_ITEM_S changeCB = {pMsgHandle, fd, pfThreadChangeOperation, pUserParam}; + + threadChangeCBList.push_back(changeCB); + + return true; +} + + void MsgProxyListener::clearListOfClosedHandle(MsgHandle* pMsgHandle) { MSG_BEGIN(); @@ -1111,6 +1138,31 @@ void MsgProxyListener::handleEvent(const MSG_EVENT_S* pMsgEvent) } mx.unlock(); + } else if (pMsgEvent->eventType == MSG_EVENT_PLG_THREAD_CHANGE_IND) { + msg_storage_change_type_t storageChangeType; + msg_thread_id_t threadId; + + /* Decode event data */ + memcpy(&storageChangeType, (void*)((char*)pMsgEvent+sizeof(MSG_EVENT_TYPE_T)+sizeof(msg_error_t)), sizeof(msg_storage_change_type_t)); + memcpy(&threadId, (void*)((char*)pMsgEvent+sizeof(MSG_EVENT_TYPE_T)+sizeof(msg_error_t)+sizeof(msg_storage_change_type_t)), sizeof(msg_thread_id_t)); + + MSG_DEBUG("storageChangeType [%d], threadId [%d]", storageChangeType, threadId); + + mx.lock(); + + MsgThreadChangeCBList::iterator it = threadChangeCBList.begin(); + + for ( ; it != threadChangeCBList.end(); it++) { + MsgHandle* pHandle = it->hAddr; + + msg_thread_change_cb pfunc = it->pfThreadChangeCB; + + void* param = it->userParam; + + pfunc((msg_handle_t)pHandle, storageChangeType, threadId, param); + } + + mx.unlock(); } else if (pMsgEvent->eventType == MSG_EVENT_PLG_INCOMING_CB_MSG_IND) { MSG_CB_MSG_S *pCbMsg = (MSG_CB_MSG_S *)pMsgEvent->data; diff --git a/utils/MsgDebug.cpp b/utils/MsgDebug.cpp index dacc4e4..4ad72be 100755 --- a/utils/MsgDebug.cpp +++ b/utils/MsgDebug.cpp @@ -218,6 +218,10 @@ const char * MsgDbgCmdStr(MSG_CMD_TYPE_T cmdType) #endif case MSG_CMD_CHECK_PERMISSION: return "MSG_CMD_CHECK_PERMISSION"; + case MSG_CMD_REG_THREAD_CHANGE_CB: + return "MSG_CMD_REG_THREAD_CHANGE_CB"; + case MSG_CMD_PLG_THREAD_CHANGE_IND: + return "MSG_CMD_PLG_THREAD_CHANGE_IND"; default: return "Unknown Command Type!!!"; @@ -426,6 +430,10 @@ const char * MsgDbgEvtStr(MSG_EVENT_TYPE_T evtType) case MSG_EVENT_PLG_REPORT_MSG_INCOMING_IND: return "MSG_EVENT_PLG_REPORT_MSG_INCOMING_IND"; + case MSG_EVENT_REG_THREAD_CHANGE_CB: + return "MSG_EVENT_REG_THREAD_CHANGE_CB"; + case MSG_EVENT_PLG_THREAD_CHANGE_IND: + return "MSG_EVENT_PLG_THREAD_CHANGE_IND"; default: return "Unknown Event Type!!!"; diff --git a/utils/MsgUtilFunction.cpp b/utils/MsgUtilFunction.cpp index fc6fd6f..3bf80da 100755 --- a/utils/MsgUtilFunction.cpp +++ b/utils/MsgUtilFunction.cpp @@ -439,6 +439,25 @@ int MsgEncodeStorageChangeData(const msg_storage_change_type_t storageChangeType } +int MsgEncodeThreadChangeData(const msg_storage_change_type_t storageChangeType, const msg_thread_id_t threadId, char **ppDest) +{ + int dataSize = 0; + + dataSize = sizeof(msg_storage_change_type_t) + sizeof(msg_thread_id_t); + + *ppDest = (char*)new char[dataSize]; + + void* p = (void*)*ppDest; + + memcpy(p, &storageChangeType, sizeof(msg_storage_change_type_t)); + p = (void*)((char*)p + sizeof(msg_storage_change_type_t)); + + memcpy(p, &threadId, sizeof(msg_thread_id_t)); + + return dataSize; +} + + int MsgEncodeReportMsgData(const msg_report_type_t msgReportType, const MSG_MESSAGE_INFO_S *pMsgInfo, char **ppDest) { int dataSize = 0; -- 2.7.4