From: Pawel Andruszkiewicz Date: Mon, 9 Feb 2015 14:58:25 +0000 (+0100) Subject: [Messaging] Removed throw/try/catch. X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~271 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d0bd874eb5af27f94445d4a8972b3a6ed5524175;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Messaging] Removed throw/try/catch. This commit consists of: 31e6edf [Messaging] Remove throw/try/catch from sendMessage(). 1305c3d [Messaging] Remove throw/try/catch from loadMessageBody(). 7a5c041 [Messaging] Remove throw/try/catch from getMessageServices(). b2e6686 [Messaging] Removed try/catch from addDraft method fcda037 [Messaging] Remove throw/try/catch from loadMessageAttachment(). e50e5ec [Messaging] Remove throw/try/catch from sync(). 409d9ab [Messaging] Remove throw/try/catch from syncFolder(). e222f4d [Messaging] Remove throw/try/catch from stopSync(). bfe0dd4 [Messaging] updateMessages and removeMessages refactored 10ad44d [Messaging] findMessages() refactored for Emails. 97fe5f7 [Messaging] try/catch removed from findConversations() 0cdd325 [Messaging] removeConversations and findFolders refactored 6e9f3d1 [Messaging] Filters refactored to not use throw 4f0aacb [Messaging] - Removing try and catch in MessageStorage a90d5a9 [Messaging] remove try/catch next part 1723e3d [Messaging] refactored throws and error-related TODOs 0800313 [Messaging] Refactored callback cleaning and removed checking type in C++ 01d4818 [Messaging] picojson .at() calls wrapped with if 9dc5931 [Messaging] Removing throws from ithe email manager constructor 7264508 [Messaging] - Checking service type in JS ee97991 [Messaging] - Removing try and catch from DBus ditectory 64c13f7 [Messaging] Removed throws from filters. MessagingEmail pass rate: 100% MessagingMMS pass rate: 100% MessagingSMS pass rate: 100% Change-Id: I4422236b59725ed6704a02b57f0ecda721f5809e (cherry picked from commit 101612406b8beed50fa8b878b11631920478184c) --- diff --git a/src/messaging/DBus/Connection.cpp b/src/messaging/DBus/Connection.cpp index c39d01bd..d912671d 100644 --- a/src/messaging/DBus/Connection.cpp +++ b/src/messaging/DBus/Connection.cpp @@ -17,7 +17,6 @@ #include "Connection.h" #include "common/logger.h" -#include "common/platform_exception.h" #include #include #include "../message_service.h" diff --git a/src/messaging/DBus/EmailSignalProxy.cpp b/src/messaging/DBus/EmailSignalProxy.cpp index 8f8739d5..ab80f51b 100644 --- a/src/messaging/DBus/EmailSignalProxy.cpp +++ b/src/messaging/DBus/EmailSignalProxy.cpp @@ -22,7 +22,6 @@ #include "EmailSignalProxy.h" #include "common/logger.h" #include -#include "common/platform_exception.h" namespace extension { namespace messaging { @@ -53,29 +52,21 @@ void EmailSignalProxy::signalCallback(GDBusConnection* connection, int status, mail_id, op_handle, error_code; char* source = NULL; - try { - g_variant_get(parameters, "(iisii)", - &status, - &mail_id, - &source, - &op_handle, - &error_code); + g_variant_get(parameters, "(iisii)", + &status, + &mail_id, + &source, + &op_handle, + &error_code); - //It is better to log this only when subclass is responsible of handling - //passed signal (usually determined by status value). - // - //LoggerD("email:\n status: %d\n mail_id: %d\n " - // "source: %s\n op_handle: %d\n error_code: %d", - // status, mail_id, source, op_handle, error_code); + //It is better to log this only when subclass is responsible of handling + //passed signal (usually determined by status value). + // + //LoggerD("email:\n status: %d\n mail_id: %d\n " + // "source: %s\n op_handle: %d\n error_code: %d", + // status, mail_id, source, op_handle, error_code); - handleEmailSignal(status, mail_id, source, op_handle, error_code); - - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", (exception.name()).c_str(), - (exception.message()).c_str()); - } catch(...) { - LoggerE("Unhandled exception!"); - } + handleEmailSignal(status, mail_id, source, op_handle, error_code); g_free(source); } diff --git a/src/messaging/DBus/EmailSignalProxy.h b/src/messaging/DBus/EmailSignalProxy.h index 74789815..9791f4b3 100644 --- a/src/messaging/DBus/EmailSignalProxy.h +++ b/src/messaging/DBus/EmailSignalProxy.h @@ -33,11 +33,12 @@ typedef std::shared_ptr EmailSignalProxyPtr; class EmailSignalProxy : public Proxy { public: - EmailSignalProxy(const std::string& proxy_path, - const std::string& proxy_iface); virtual ~EmailSignalProxy(); protected: + EmailSignalProxy(const std::string& proxy_path, + const std::string& proxy_iface); + /** * Override this method in subclass to handle email signal */ diff --git a/src/messaging/DBus/LoadAttachmentProxy.cpp b/src/messaging/DBus/LoadAttachmentProxy.cpp index f875898b..31624797 100644 --- a/src/messaging/DBus/LoadAttachmentProxy.cpp +++ b/src/messaging/DBus/LoadAttachmentProxy.cpp @@ -22,7 +22,7 @@ #include "LoadAttachmentProxy.h" #include "common/logger.h" -#include "common/platform_exception.h" +#include "common/platform_result.h" #include #include @@ -37,11 +37,13 @@ namespace extension { namespace messaging { namespace DBus { +using namespace common; + /** * This method perform very specified task (see warning comment) so it should not be * visible outside LoadAttachmentProxy class. */ -void updateAttachmentDataWithEmailGetAttachmentData( +PlatformResult updateAttachmentDataWithEmailGetAttachmentData( std::shared_ptr attachment) { struct ScopedEmailAttachmentData { @@ -72,7 +74,7 @@ void updateAttachmentDataWithEmailGetAttachmentData( if (EMAIL_ERROR_NONE != err || NULL == attachment_data_holder.data) { LoggerE("Couldn't get attachment data for attachmentId:%d", attachment->getId()); - throw common::UnknownException("Couldn't get attachment."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Couldn't get attachment."); } LoggerD("attachment name : %s", attachment_data_holder->attachment_name); @@ -91,6 +93,7 @@ void updateAttachmentDataWithEmailGetAttachmentData( } isSaved = attachment_data_holder->save_status; attachment->setIsSaved(isSaved); + return PlatformResult(ErrorCode::NO_ERROR); } LoadAttachmentProxy::LoadAttachmentProxy(const std::string& path, @@ -103,6 +106,19 @@ LoadAttachmentProxy::~LoadAttachmentProxy() { } +PlatformResult LoadAttachmentProxy::create(const std::string& path, + const std::string& iface, + LoadAttachmentProxyPtr* load_attachment_proxy) { + load_attachment_proxy->reset(new LoadAttachmentProxy(path, iface)); + if ((*load_attachment_proxy)->isNotProxyGot()) { + LoggerE("Could not get load attachment proxy"); + load_attachment_proxy->reset(); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not get load attachment proxy"); + } else { + return PlatformResult(ErrorCode::NO_ERROR); + } +} + void LoadAttachmentProxy::addCallback(MessageAttachmentCallbackData* callbackOwned) { if(callbackOwned->getMessageAttachment()) { @@ -167,68 +183,50 @@ void LoadAttachmentProxy::handleEmailSignal(const int status, // and not handle returned from above call!! const int nth = op_handle; - try { - // From old implementation it looks that op_handle(nth) is is equal to - // index (1 based) of attachment inside email thus it is not globally unique! - // Therfore we need to test if mail_id match. - // For details see old implementation MailSync.cp line 461 - - callback = findCallback(nth, mail_id); - if(!callback) { - //We should not log not found pair since it could be requested by - //different application. - return; - } + // From old implementation it looks that op_handle(nth) is is equal to + // index (1 based) of attachment inside email thus it is not globally unique! + // Therfore we need to test if mail_id match. + // For details see old implementation MailSync.cp line 461 + + callback = findCallback(nth, mail_id); + if(!callback) { + //We should not log not found pair since it could be requested by + //different application. + return; + } - LoggerD("Found callback for pair mailId:%d nth:%d", mail_id, nth); + LoggerD("Found callback for pair mailId:%d nth:%d", mail_id, nth); - if(NOTI_DOWNLOAD_ATTACH_FINISH == status) { - LoggerD("Message attachment downloaded!"); + PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR); + if(NOTI_DOWNLOAD_ATTACH_FINISH == status) { + LoggerD("Message attachment downloaded!"); - std::shared_ptr att = callback->getMessageAttachment(); - updateAttachmentDataWithEmailGetAttachmentData(att); + std::shared_ptr att = callback->getMessageAttachment(); + ret = updateAttachmentDataWithEmailGetAttachmentData(att); + if (!ret.IsError()) { LoggerD("Updated Message attachment object"); - try { - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - picojson::object args; - args[JSON_DATA_MESSAGE_ATTACHMENT] = MessagingUtil::messageAttachmentToJson( - callback->getMessageAttachment()); - obj[JSON_DATA] = picojson::value(args); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } catch (...) { - LoggerW("Couldn't create JSMessageAttachment object!"); - throw common::UnknownException( - "Couldn't create JSMessageAttachment object!"); - } + auto json = callback->getJson(); + picojson::object& obj = json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + picojson::object args; + args[JSON_DATA_MESSAGE_ATTACHMENT] = MessagingUtil::messageAttachmentToJson( + callback->getMessageAttachment()); + obj[JSON_DATA] = picojson::value(args); - } else if(NOTI_DOWNLOAD_ATTACH_FAIL) { - LoggerD("Load message attachment failed!"); - common::UnknownException e("Load message attachment failed!"); - callback->setError(e.name(), e.message()); PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() ); } - } catch (const common::PlatformException& e) { - LoggerE("Exception in signal callback"); - callback->setError(e.name(), e.message()); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } catch (...) { + } else if(NOTI_DOWNLOAD_ATTACH_FAIL) { + LoggerD("Load message attachment failed!"); + ret = PlatformResult(ErrorCode::UNKNOWN_ERR, "Load message attachment failed!"); + } + if (ret.IsError()) { LoggerE("Exception in signal callback"); - common::UnknownException e("Exception in signal callback"); - callback->setError(e.name(), e.message()); + callback->setError(ret); PostQueue::getInstance().resolve( callback->getJson()->get().at(JSON_CALLBACK_ID).get(), callback->getJson()->serialize() diff --git a/src/messaging/DBus/LoadAttachmentProxy.h b/src/messaging/DBus/LoadAttachmentProxy.h index 8e3f2f38..9a163c18 100644 --- a/src/messaging/DBus/LoadAttachmentProxy.h +++ b/src/messaging/DBus/LoadAttachmentProxy.h @@ -22,6 +22,7 @@ #ifndef __TIZEN_DBUS_LOAD_ATTACHMENT_PROXY_H__ #define __TIZEN_DBUS_LOAD_ATTACHMENT_PROXY_H__ +#include "common/platform_result.h" #include "EmailSignalProxy.h" #include @@ -41,15 +42,18 @@ public: // Callback is owned by this set typedef std::set CallbackSet; - LoadAttachmentProxy(const std::string& path, - const std::string& iface); virtual ~LoadAttachmentProxy(); + static common::PlatformResult create(const std::string& path, + const std::string& iface, + LoadAttachmentProxyPtr* load_attachment_proxy); //Passed callback will be owned by this proxy void addCallback(MessageAttachmentCallbackData* callbackOwned); void removeCallback(MessageAttachmentCallbackData* callback); protected: + LoadAttachmentProxy(const std::string& path, + const std::string& iface); virtual void handleEmailSignal(const int status, const int mail_id, const std::string& source, diff --git a/src/messaging/DBus/LoadBodyProxy.cpp b/src/messaging/DBus/LoadBodyProxy.cpp index 68cb03b6..5c0d8cb9 100644 --- a/src/messaging/DBus/LoadBodyProxy.cpp +++ b/src/messaging/DBus/LoadBodyProxy.cpp @@ -35,7 +35,7 @@ #include "common/logger.h" #include -#include "common/platform_exception.h" +#include "common/platform_result.h" #include "../message.h" #include "../message_body.h" @@ -45,16 +45,29 @@ namespace extension { namespace messaging { namespace DBus { +using namespace common; + LoadBodyProxy::LoadBodyProxy(const std::string& path, const std::string& iface) : EmailSignalProxy(path, iface) { - } LoadBodyProxy::~LoadBodyProxy() { +} +PlatformResult LoadBodyProxy::create(const std::string& path, + const std::string& iface, + LoadBodyProxyPtr* load_body_proxy) { + load_body_proxy->reset(new LoadBodyProxy(path, iface)); + if ((*load_body_proxy)->isNotProxyGot()) { + LoggerE("Could not get load body proxy"); + load_body_proxy->reset(); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not get load body proxy"); + } else { + return PlatformResult(ErrorCode::NO_ERROR); + } } void LoadBodyProxy::addCallback(MessageBodyCallbackData* callbackOwned) @@ -125,105 +138,82 @@ void LoadBodyProxy::handleEmailSignal(const int status, } MessageBodyCallbackData* callback = NULL; - try { - callback = findCallbackByOpHandle(op_handle); - if (!callback) { - LoggerE("Callback is null"); - } else { - if( (NOTI_DOWNLOAD_BODY_FINISH == status) || - (NOTI_DOWNLOAD_BODY_FAIL == status && - EMAIL_ERROR_MAIL_IS_ALREADY_DOWNLOADED == error_code)) { - - // Old implementation is not verifying whether message update failed, - // it just calls success callback. - if(callback->getMessage()) { - email_mail_data_t* mail_data = EmailManager::loadMessage( - callback->getMessage()->getId()); - if (mail_data) { - callback->getMessage()->updateEmailMessage(*mail_data); + + callback = findCallbackByOpHandle(op_handle); + if (!callback) { + LoggerE("Callback is null"); + } else { + PlatformResult ret = PlatformResult(ErrorCode::NO_ERROR); + if( (NOTI_DOWNLOAD_BODY_FINISH == status) || + (NOTI_DOWNLOAD_BODY_FAIL == status && + EMAIL_ERROR_MAIL_IS_ALREADY_DOWNLOADED == error_code)) { + + // Old implementation is not verifying whether message update failed, + // it just calls success callback. + if(callback->getMessage()) { + email_mail_data_t* mail_data = EmailManager::loadMessage( + callback->getMessage()->getId()); + if (mail_data) { + ret = callback->getMessage()->updateEmailMessage(*mail_data); + if (!ret.IsError()) { EmailManager::freeMessage(mail_data); mail_data = NULL; } - - //TODO: this should be reviewed when attachments and - // loadAttachments have been completed. - //TODO: see old implementation lines 608-635 in MailSync.cpp - /* - * This is original Messaging implementation: - * - * std::vector attachments = mail->getAttachments(); - * std::vector inlineAttachments = mail->getInlineAttachments(); - * - * for (unsigned int idx = 0; idx < attachments.size() ; idx++ ) - * { - * LoggerD("set Attachment ID = " << attachments[idx]->getAttachmentID()); - * attachments[idx]->setMessage(event->m_message); - * - * } - * for (unsigned int idx = 0; idx < inlineAttachments.size() ; idx++ ) - * { - * LoggerD("set inline Attachment ID = " << inlineAttachments[idx]->getAttachmentID()); - * inlineAttachments[idx]->setMessage(event->m_message); - * } - */ } - LoggerD("Message body downloaded!"); - try { - LoggerD("Calling success callback"); - - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - picojson::object args; - args[JSON_DATA_MESSAGE_BODY] = MessagingUtil::messageBodyToJson( - callback->getMessage()->getBody()); - obj[JSON_DATA] = picojson::value(args); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } catch (...) { - LoggerW("Couldn't create JSMessage object!"); - throw common::UnknownException( - "Couldn't create JSMessage object!"); - } + //TODO: this should be reviewed when attachments and + // loadAttachments have been completed. + //TODO: see old implementation lines 608-635 in MailSync.cpp + // + // This is original Messaging implementation: + // + // std::vector attachments = mail->getAttachments(); + // std::vector inlineAttachments = mail->getInlineAttachments(); + // + // for (unsigned int idx = 0; idx < attachments.size() ; idx++ ) + // { + // LoggerD("set Attachment ID = " << attachments[idx]->getAttachmentID()); + // attachments[idx]->setMessage(event->m_message); + // + // } + // for (unsigned int idx = 0; idx < inlineAttachments.size() ; idx++ ) + // { + // LoggerD("set inline Attachment ID = " << inlineAttachments[idx]->getAttachmentID()); + // inlineAttachments[idx]->setMessage(event->m_message); + // } + // + } - } else if(NOTI_DOWNLOAD_BODY_FAIL == status) { - LoggerD("Load message body failed!"); + if (!ret.IsError()) { + LoggerD("Calling success callback"); + + auto json = callback->getJson(); + picojson::object& obj = json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + picojson::object args; + args[JSON_DATA_MESSAGE_BODY] = MessagingUtil::messageBodyToJson( + callback->getMessage()->getBody()); + obj[JSON_DATA] = picojson::value(args); - common::UnknownException e("Load message body failed!"); - callback->setError(e.name(), e.message()); PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() ); } + } else if(NOTI_DOWNLOAD_BODY_FAIL == status) { + LoggerD("Load message body failed!"); + ret = PlatformResult(ErrorCode::UNKNOWN_ERR, "Load message body failed!"); + } + + if (ret.IsError()) { + callback->setError(ret); + PostQueue::getInstance().resolve( + callback->getJson()->get().at(JSON_CALLBACK_ID).get(), + callback->getJson()->serialize() + ); } - } - catch (const common::PlatformException& e) { - LoggerE("Exception in signal callback"); - - callback->setError(e.name(), e.message()); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } - catch (...) { - LoggerE("Exception in signal callback"); - - common::UnknownException e("Load message body failed!"); - callback->setError(e.name(), e.message()); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } - if(callback) { removeCallback(callback); delete callback; } diff --git a/src/messaging/DBus/LoadBodyProxy.h b/src/messaging/DBus/LoadBodyProxy.h index 0ed55090..69f29c30 100644 --- a/src/messaging/DBus/LoadBodyProxy.h +++ b/src/messaging/DBus/LoadBodyProxy.h @@ -22,6 +22,7 @@ #ifndef __TIZEN_DBUS_LOAD_BODY_PROXY_H__ #define __TIZEN_DBUS_LOAD_BODY_PROXY_H__ +#include "common/platform_result.h" #include "EmailSignalProxy.h" #include @@ -41,15 +42,18 @@ public: // Callback is owned by this set typedef std::set CallbackSet; - LoadBodyProxy(const std::string& path, - const std::string& iface); virtual ~LoadBodyProxy(); + static common::PlatformResult create(const std::string& path, + const std::string& iface, + LoadBodyProxyPtr* load_body_proxy); //Passed callback will be owned by this proxy void addCallback(MessageBodyCallbackData* callbackOwned); void removeCallback(MessageBodyCallbackData* callback); protected: + LoadBodyProxy(const std::string& path, + const std::string& iface); virtual void handleEmailSignal(const int status, const int mail_id, const std::string& source, diff --git a/src/messaging/DBus/MessageProxy.cpp b/src/messaging/DBus/MessageProxy.cpp index 2c1dd059..b986adef 100644 --- a/src/messaging/DBus/MessageProxy.cpp +++ b/src/messaging/DBus/MessageProxy.cpp @@ -17,24 +17,20 @@ #include "MessageProxy.h" #include "Connection.h" - #include "common/logger.h" -#include "common/platform_exception.h" - #include "../message.h" #include "../message_email.h" - #include "../message_conversation.h" //#include - #include "../change_listener_container.h" - #include "../email_manager.h" namespace extension { namespace messaging { namespace DBus { +using namespace common; + MessageProxy::MessageProxy(): Proxy(Proxy::DBUS_PATH_EMAIL_STORAGE_CHANGE, Proxy::DBUS_IFACE_EMAIL_STORAGE_CHANGE, @@ -48,6 +44,17 @@ MessageProxy::~MessageProxy() { } +PlatformResult MessageProxy::create(MessageProxyPtr* message_proxy) { + message_proxy->reset(new MessageProxy()); + if ((*message_proxy)->isNotProxyGot()) { + LoggerE("Could not get proxy"); + message_proxy->reset(); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not get proxy"); + } else { + return PlatformResult(ErrorCode::NO_ERROR); + } +} + void MessageProxy::signalCallback(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, @@ -70,44 +77,42 @@ void MessageProxy::signalCallback(GDBusConnection *connection, LoggerD("name: %s", name); LoggerD("thread_id: %d", thread_id); - try { - switch (status) { - case NOTI_MAIL_ADD: - case NOTI_MAIL_UPDATE: - handleEmailEvent(account_id, object_id, thread_id, status); - break; - case NOTI_MAIL_DELETE: - //ids of removing messages are sent with name in format: - //id1,id2,id3, - handleEmailRemoveEvent(account_id, name); - break; - case NOTI_MAIL_DELETE_FINISH: - case NOTI_MAIL_DELETE_FAIL: - //notify EmailManager, maybe it tries to delete mail - notifyEmailManager(name, static_cast(status)); - break; - case NOTI_THREAD_DELETE: - handleThreadRemoveEvent(account_id, object_id); - break; - case NOTI_MAILBOX_ADD: - case NOTI_MAILBOX_UPDATE: - case NOTI_MAILBOX_FIELD_UPDATE: - case NOTI_MAILBOX_RENAME: - case NOTI_MAILBOX_DELETE: - handleMailboxEvent(account_id, object_id, status); - break; - default: - LoggerD("Unrecognized status: %d", status); - } - } catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Failed to call callback"); + PlatformResult ret(ErrorCode::NO_ERROR); + switch (status) { + case NOTI_MAIL_ADD: + case NOTI_MAIL_UPDATE: + ret = handleEmailEvent(account_id, object_id, thread_id, status); + break; + case NOTI_MAIL_DELETE: + //ids of removing messages are sent with name in format: + //id1,id2,id3, + handleEmailRemoveEvent(account_id, name); + break; + case NOTI_MAIL_DELETE_FINISH: + case NOTI_MAIL_DELETE_FAIL: + //notify EmailManager, maybe it tries to delete mail + notifyEmailManager(name, static_cast(status)); + break; + case NOTI_THREAD_DELETE: + handleThreadRemoveEvent(account_id, object_id); + break; + case NOTI_MAILBOX_ADD: + case NOTI_MAILBOX_UPDATE: + case NOTI_MAILBOX_FIELD_UPDATE: + case NOTI_MAILBOX_RENAME: + case NOTI_MAILBOX_DELETE: + ret = handleMailboxEvent(account_id, object_id, status); + break; + default: + LoggerD("Unrecognized status: %d", status); + } + if (ret.IsError()){ + LoggerE("%d (%s)", ret.error_code(), (ret.message()).c_str()); } g_free(name); } -void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id, int event) +PlatformResult MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id, int event) { LoggerD("Enter"); @@ -119,7 +124,10 @@ void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id, if (mail_data) email_free_mail_data(&mail_data, 1); LoggerE("Failed to get mail data during setting conversation id in MessageProxy."); - return; + //TODO maybe error should be ignored + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Failed to get mail data during setting" + " conversation id in MessageProxy."); } thread_id = mail_data->thread_id; @@ -131,11 +139,15 @@ void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id, email_mail_data_t* mail_data = EmailManager::getInstance().loadMessage(mail_id); if (mail_data == NULL) { - throw common::UnknownException("Failed to load email"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to load email"); } - std::shared_ptr msg = Message::convertPlatformEmailToObject(*mail_data); - ConversationPtr conv = MessageConversation::convertEmailConversationToObject( - thread_id); + std::shared_ptr msg; + PlatformResult ret = Message::convertPlatformEmailToObject(*mail_data, &msg); + if (ret.IsError()) return ret; + ConversationPtr conv; + ret = MessageConversation::convertEmailConversationToObject( + thread_id, &conv); + if (ret.IsError()) return ret; EventMessages* eventMsg = new EventMessages(); eventMsg->service_type = MessageType::EMAIL; @@ -169,6 +181,7 @@ void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id, delete eventConv; EmailManager::getInstance().freeMessage(mail_data); + return PlatformResult(ErrorCode::NO_ERROR); } std::vector getMailIds(const std::string& idsString) @@ -242,7 +255,7 @@ void MessageProxy::handleThreadRemoveEvent(int account_id, int thread_id) eventConv = NULL; } -void MessageProxy::handleMailboxEvent(int account_id, int mailbox_id, int event) +PlatformResult MessageProxy::handleMailboxEvent(int account_id, int mailbox_id, int event) { LoggerD("Enter"); EventFolders* eventFolder = new EventFolders(); @@ -265,7 +278,7 @@ void MessageProxy::handleMailboxEvent(int account_id, int mailbox_id, int event) if (EMAIL_ERROR_NONE != email_get_mailbox_by_mailbox_id(mailbox_id, &mail_box)) { LoggerE("Mailbox not retrieved"); delete eventFolder; - throw common::UnknownException("Failed to load mailbox"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to load mailbox"); } folder.reset(new MessageFolder(*mail_box)); if (EMAIL_ERROR_NONE != email_free_mailbox(&mail_box, 1)) { @@ -288,6 +301,7 @@ void MessageProxy::handleMailboxEvent(int account_id, int mailbox_id, int event) LoggerW("Unknown event type: %d", event); } delete eventFolder; + return PlatformResult(ErrorCode::NO_ERROR); } } //namespace DBus diff --git a/src/messaging/DBus/MessageProxy.h b/src/messaging/DBus/MessageProxy.h index 1b8f040f..81e8a3bc 100644 --- a/src/messaging/DBus/MessageProxy.h +++ b/src/messaging/DBus/MessageProxy.h @@ -26,16 +26,21 @@ #include #include #include "Proxy.h" +#include "common/platform_result.h" namespace extension { namespace messaging { namespace DBus { +class MessageProxy; +typedef std::shared_ptr MessageProxyPtr; + class MessageProxy: public Proxy { public: - MessageProxy(); virtual ~MessageProxy(); + static common::PlatformResult create(MessageProxyPtr* message_proxy); protected: + MessageProxy(); virtual void signalCallback(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, @@ -49,15 +54,13 @@ protected: * @param thread_id * @param event */ - void handleEmailEvent(int account_id, int mail_id, int thread_id, int event); + common::PlatformResult handleEmailEvent(int account_id, int mail_id, int thread_id, int event); void handleEmailRemoveEvent(int account_id, const std::string& idsString); void notifyEmailManager(const std::string& idsString, email_noti_on_storage_event status); void handleThreadRemoveEvent(int account_id, int thread_id); - void handleMailboxEvent(int account_id, int mailbox_id, int event); + common::PlatformResult handleMailboxEvent(int account_id, int mailbox_id, int event); }; -typedef std::shared_ptr MessageProxyPtr; - } //namespace DBus } //namespace messaging } //namespace extension diff --git a/src/messaging/DBus/Proxy.cpp b/src/messaging/DBus/Proxy.cpp index c7c817e2..2dddfb1b 100644 --- a/src/messaging/DBus/Proxy.cpp +++ b/src/messaging/DBus/Proxy.cpp @@ -21,7 +21,7 @@ #include "Proxy.h" #include "common/logger.h" -#include "common/platform_exception.h" +#include "common/platform_result.h" #include #include #include "../message_service.h" @@ -30,6 +30,8 @@ namespace extension { namespace messaging { namespace DBus { +using namespace common; + const char* Proxy::DBUS_PATH_NETWORK_STATUS = "/User/Email/NetworkStatus"; const char* Proxy::DBUS_IFACE_NETWORK_STATUS = "User.Email.NetworkStatus"; const char* Proxy::DBUS_PATH_EMAIL_STORAGE_CHANGE = "/User/Email/StorageChange"; @@ -65,10 +67,6 @@ Proxy::Proxy(const std::string& proxy_path, m_proxy = g_dbus_proxy_new_sync(m_conn.getDBus(), G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, NULL, unique_name, m_path.c_str(), m_iface.c_str(), NULL, &m_error); - if (!m_proxy || m_error) { - LoggerE("Could not get proxy"); - throw common::UnknownException("Could not get proxy"); - } } Proxy::~Proxy() @@ -90,21 +88,12 @@ void Proxy::signalCallbackProxy(GDBusConnection *connection, return; } - try { - //It is better to log this only when subclass is responsible of handling - //passed signal. If you need it put it into your signalCallback(...) method - //LoggerD("signal: %s from: %s path: %s interface: %s", - // signal_name, sender_name, object_path, interface_name); - - this_ptr->signalCallback(connection, sender_name, object_path, interface_name, - signal_name, parameters); - - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", (exception.name()).c_str(), - (exception.message()).c_str()); - } catch(...) { - LoggerE("Unhandled exception!"); - } + //It is better to log this only when subclass is responsible of handling + //passed signal. If you need it put it into your signalCallback(...) method + //LoggerD("signal: %s from: %s path: %s interface: %s", + // signal_name, sender_name, object_path, interface_name); + this_ptr->signalCallback(connection, sender_name, object_path, interface_name, + signal_name, parameters); } void Proxy::signalSubscribe() diff --git a/src/messaging/DBus/Proxy.h b/src/messaging/DBus/Proxy.h index 4db19c0e..81622511 100644 --- a/src/messaging/DBus/Proxy.h +++ b/src/messaging/DBus/Proxy.h @@ -29,7 +29,7 @@ #include #include "common/callback_user_data.h" #include "common/picojson.h" -#include "common/platform_exception.h" +#include "common/platform_result.h" #include "../messaging_instance.h" namespace extension { @@ -56,7 +56,17 @@ public: * Name of email signal */ static const char* DBUS_NAME_SIGNAL_EMAIL; + virtual ~Proxy(); + bool isNotProxyGot() { return !m_proxy || m_error; }; + + void signalSubscribe(); + void signalUnsubscribe(); + const std::string& getSignalName() const; + const std::string& getSignalPath() const; + const std::string& getSignalInterfaceName() const; + +protected: /** * @param proxy_path - path of this proxy * @param proxy_iface - interface name of this proxy @@ -70,17 +80,6 @@ public: const std::string& signal_name, const std::string& signal_path, const std::string& signal_iface); - - virtual ~Proxy(); - - void signalSubscribe(); - void signalUnsubscribe(); - - const std::string& getSignalName() const; - const std::string& getSignalPath() const; - const std::string& getSignalInterfaceName() const; - -protected: /** * Please implement this method in subclass to handle signal. * Executed by static void signalCallbackProxy(...). @@ -98,6 +97,7 @@ private: * DBus when signal is received. It calls * (static_cast(user_data))->signalCallback(...) */ + static void signalCallbackProxy(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, diff --git a/src/messaging/DBus/SendProxy.cpp b/src/messaging/DBus/SendProxy.cpp index f65fc96a..be938411 100644 --- a/src/messaging/DBus/SendProxy.cpp +++ b/src/messaging/DBus/SendProxy.cpp @@ -26,6 +26,8 @@ namespace extension { namespace messaging { namespace DBus { +using namespace common; + SendProxy::SendProxy(): EmailSignalProxy(Proxy::DBUS_PATH_NETWORK_STATUS, Proxy::DBUS_IFACE_NETWORK_STATUS) @@ -36,6 +38,17 @@ SendProxy::~SendProxy() { } +PlatformResult SendProxy::create(SendProxyPtr* send_proxy) { + send_proxy->reset(new SendProxy()); + if ((*send_proxy)->isNotProxyGot()) { + LoggerE("Could not get send proxy"); + send_proxy->reset(); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not get send proxy"); + } else { + return PlatformResult(ErrorCode::NO_ERROR); + } +} + void SendProxy::handleEmailSignal(const int status, const int account_id, const std::string& source, diff --git a/src/messaging/DBus/SendProxy.h b/src/messaging/DBus/SendProxy.h index 7ed66eba..ef7d5ef5 100644 --- a/src/messaging/DBus/SendProxy.h +++ b/src/messaging/DBus/SendProxy.h @@ -18,27 +18,29 @@ #ifndef __TIZEN_SEND_PROXY_H #define __TIZEN_SEND_PROXY_H +#include "common/platform_result.h" #include "EmailSignalProxy.h" namespace extension { namespace messaging { namespace DBus { +class SendProxy; +typedef std::shared_ptr SendProxyPtr; + class SendProxy: public EmailSignalProxy { public: - SendProxy(); virtual ~SendProxy(); + static common::PlatformResult create(SendProxyPtr* send_proxy); protected: + SendProxy(); virtual void handleEmailSignal(const int status, const int account_id, const std::string& source, const int op_handle, const int error_code); - }; -typedef std::shared_ptr SendProxyPtr; - } //DBus } //messaging } //extension diff --git a/src/messaging/DBus/SyncProxy.cpp b/src/messaging/DBus/SyncProxy.cpp index f7c5703e..63d98900 100644 --- a/src/messaging/DBus/SyncProxy.cpp +++ b/src/messaging/DBus/SyncProxy.cpp @@ -21,7 +21,7 @@ #include "SyncProxy.h" #include "common/logger.h" -#include "common/platform_exception.h" +#include "common/platform_result.h" #include #include #include "../message_service.h" @@ -30,6 +30,8 @@ namespace extension { namespace messaging { namespace DBus { +using namespace common; + SyncProxy::SyncProxy(const std::string& path, const std::string& iface) : EmailSignalProxy(path, iface) @@ -42,36 +44,45 @@ SyncProxy::~SyncProxy() } +PlatformResult SyncProxy::create(const std::string& path, + const std::string& iface, + SyncProxyPtr* sync_proxy) { + sync_proxy->reset(new SyncProxy(path, iface)); + if ((*sync_proxy)->isNotProxyGot()) { + LoggerE("Could not get sync proxy"); + sync_proxy->reset(); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not get sync proxy"); + } else { + return PlatformResult(ErrorCode::NO_ERROR); + } +} + void SyncProxy::addCallback(long op_id, common::CallbackUserData* callbackOwned) { m_callback_map.insert(std::make_pair(op_id, callbackOwned)); } -common::CallbackUserData* SyncProxy::getCallback(long op_id) -{ - common::CallbackUserData* cb = NULL; - CallbackMap::iterator it = m_callback_map.find(op_id); - if (it != m_callback_map.end()) { - cb = it->second; - return cb; - } +common::CallbackUserData* SyncProxy::getCallback(long op_id) { + common::CallbackUserData* cb = nullptr; + const auto it = m_callback_map.find(op_id); + + if (it != m_callback_map.end()) { + cb = it->second; + } else { LoggerE("Could not find callback"); - throw common::UnknownException("Could not find callback"); - return cb; + } + + return cb; } -void SyncProxy::removeCallback(long op_id){ - CallbackMap::iterator it = m_callback_map.find(op_id); - if (it != m_callback_map.end()) { - common::CallbackUserData* cb = it->second; - delete cb; - cb = NULL; - m_callback_map.erase(it); - } - else { - LoggerE("Could not find callback"); - throw common::UnknownException("Could not find callback"); - } +void SyncProxy::removeCallback(long op_id) { + auto it = m_callback_map.find(op_id); + if (it != m_callback_map.end()) { + delete it->second; + m_callback_map.erase(it); + } else { + LoggerE("Could not find callback"); + } } void SyncProxy::handleEmailSignal(const int status, @@ -100,70 +111,62 @@ void SyncProxy::handleEmailSignal(const int status, common::CallbackUserData* callback = NULL; CallbackMap::iterator callback_it; - try { - callback_it = findSyncCallbackByOpHandle(op_handle); - callback = callback_it->second; - if (!callback) { - LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } + PlatformResult ret = findSyncCallbackByOpHandle(op_handle, &callback_it); + if (ret.IsError()) { + LoggerE("Failed to find callback by handle - (%s)", ret.message().c_str()); + return; + } + + callback = callback_it->second; + if (!callback) { + LoggerE("Callback is null"); + return; + } - std::shared_ptr response = callback->getJson(); - picojson::object& obj = response->get(); - switch (status) { - case NOTI_DOWNLOAD_FINISH: - LoggerD("Sync finished!"); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - response->serialize() - ); - break; - - case NOTI_DOWNLOAD_FAIL: - { - LoggerD("Sync failed!"); - common::UnknownException err("Sync failed!"); - callback->setError(err.name(), err.message()); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - response->serialize() - ); - } + std::shared_ptr response = callback->getJson(); + picojson::object& obj = response->get(); + switch (status) { + case NOTI_DOWNLOAD_FINISH: + LoggerD("Sync finished!"); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + response->serialize() + ); break; - default: - break; + case NOTI_DOWNLOAD_FAIL: + { + LoggerD("Sync failed!"); + common::UnknownException err("Sync failed!"); + callback->setError(err.name(), err.message()); + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + response->serialize() + ); } - } - catch (const common::PlatformException& e) { - // this situation may occur when there is no callback in the - // map with specified opId (for example stopSync() has - // removed it), but sync() was already started - only - // warning here: - LoggerE("Exception in signal callback"); - } - catch(...) - { - LoggerE("Exception in signal callback"); + break; + + default: + break; } - if(callback) { + if (callback) { delete callback; m_callback_map.erase(callback_it); } } -SyncProxy::CallbackMap::iterator SyncProxy::findSyncCallbackByOpHandle( - const int op_handle) +PlatformResult SyncProxy::findSyncCallbackByOpHandle(const int op_handle, + SyncProxy::CallbackMap::iterator* it) { - CallbackMap::iterator it = m_callback_map.begin(); - for (; it != m_callback_map.end(); ++it) { - SyncCallbackData* cb = dynamic_cast(it->second); + *it = m_callback_map.begin(); + for (; *it != m_callback_map.end(); ++(*it)) { + SyncCallbackData* cb = dynamic_cast((*it)->second); if (!cb) continue; if (op_handle == cb->getOperationHandle()) { - return it; + return PlatformResult(ErrorCode::NO_ERROR); } } // this situation may occur when there is no callback in the @@ -171,7 +174,7 @@ SyncProxy::CallbackMap::iterator SyncProxy::findSyncCallbackByOpHandle( // removed it), but sync() was already started - only // warning here: LoggerW("Could not find callback with op_handle: %d", op_handle); - throw common::UnknownException("Could not find callback"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not find callback"); } } //namespace DBus diff --git a/src/messaging/DBus/SyncProxy.h b/src/messaging/DBus/SyncProxy.h index eff69241..bd7f3794 100644 --- a/src/messaging/DBus/SyncProxy.h +++ b/src/messaging/DBus/SyncProxy.h @@ -23,6 +23,7 @@ #define __TIZEN_DBUS_SYNC_PROXY_H__ #include "EmailSignalProxy.h" +#include "common/platform_result.h" namespace extension { namespace messaging { @@ -37,16 +38,20 @@ public: // Callback is owned by this map typedef std::map CallbackMap; - SyncProxy(const std::string& path, - const std::string& iface); virtual ~SyncProxy(); + static common::PlatformResult create(const std::string& path, + const std::string& iface, + SyncProxyPtr* sync_proxy); //Passed callback will be owned by this proxy void addCallback(long op_id, common::CallbackUserData* callbackOwned); common::CallbackUserData* getCallback(long op_id); void removeCallback(long op_id); protected: + SyncProxy(const std::string& path, + const std::string& iface); + virtual void handleEmailSignal(const int status, const int mail_id, const std::string& source, @@ -58,8 +63,8 @@ private: * Find callback by operation handle returned from: * int email_sync_header(..., int *handle); */ - CallbackMap::iterator findSyncCallbackByOpHandle(const int op_handle); - + common::PlatformResult findSyncCallbackByOpHandle(const int op_handle, + CallbackMap::iterator* it); CallbackMap m_callback_map; }; diff --git a/src/messaging/MsgCommon/AbstractFilter.cpp b/src/messaging/MsgCommon/AbstractFilter.cpp index dd9df7b4..6fb417ae 100644 --- a/src/messaging/MsgCommon/AbstractFilter.cpp +++ b/src/messaging/MsgCommon/AbstractFilter.cpp @@ -46,7 +46,7 @@ FilterType AbstractFilter::getFilterType() const bool AbstractFilter::isMatching(const FilterableObject* const tested_object) const { LoggerE("Calling isMatching on AbstractFilter!"); - throw UnknownException("Method not supported"); + return false; } AttributeFilterPtr castToAttributeFilter(AbstractFilterPtr from) @@ -168,34 +168,24 @@ bool FilterUtils::isTimeStampInRange(const time_t& time_stamp, bool initial_is_valid_time_value = false; if (initial_value && !initial_value->isNullOrUndefined()) { - try { - struct tm ftime; // TODO = *initial_value->toDateTm(); - from_time = mktime(&ftime); - initial_is_valid_time_value = true; - } - catch(...) { - LoggerE("Unknown exception occured during execution of Any::toDateTm()"); - } + struct tm ftime = *initial_value->toDateTm(); + from_time = mktime(&ftime); + initial_is_valid_time_value = true; } - if(!initial_is_valid_time_value) { + if (!initial_is_valid_time_value) { LoggerE("initialValue is not Time!"); - throw InvalidValuesException("initialValue is not Time!"); + return false; } bool end_is_valid_time_value = false; if (end_value && !end_value->isNullOrUndefined()) { - try { - struct tm ttime; // TODO = *end_value->toDateTm(); - to_time = mktime(&ttime); - end_is_valid_time_value = true; - } - catch(...) { - LoggerE("Unknown exception occured during execution of Any::toDateTm()"); - } + struct tm ttime = *end_value->toDateTm(); + to_time = mktime(&ttime); + end_is_valid_time_value = true; } - if(end_is_valid_time_value) { + if (end_is_valid_time_value) { LoggerE("endValue is not Time!"); - throw InvalidValuesException("endValue is not Time!"); + return false; } bool is_in_range = FilterUtils::isBetweenTimeRange(time_stamp, from_time, to_time); diff --git a/src/messaging/MsgCommon/AttributeFilter.cpp b/src/messaging/MsgCommon/AttributeFilter.cpp index 1943d717..e39c263e 100644 --- a/src/messaging/MsgCommon/AttributeFilter.cpp +++ b/src/messaging/MsgCommon/AttributeFilter.cpp @@ -65,9 +65,9 @@ void AttributeFilter::setMatchValue(AnyPtr match_value) bool AttributeFilter::isMatching(const FilterableObject* const filtered_object) const { - if(!filtered_object) { + if (!filtered_object) { LoggerE("Invalid object: NULL!"); - throw common::InvalidValuesException("Invalid object"); + return false; } return filtered_object->isMatchingAttribute(m_attribute_name, m_match_flag, diff --git a/src/messaging/MsgCommon/AttributeRangeFilter.cpp b/src/messaging/MsgCommon/AttributeRangeFilter.cpp index 6a754c5b..6a5e5896 100644 --- a/src/messaging/MsgCommon/AttributeRangeFilter.cpp +++ b/src/messaging/MsgCommon/AttributeRangeFilter.cpp @@ -66,9 +66,9 @@ void AttributeRangeFilter::setEndValue(AnyPtr end_value) bool AttributeRangeFilter::isMatching(const FilterableObject* const filtered_object) const { - if(!filtered_object) { + if (!filtered_object) { LoggerE("Invalid object: NULL!"); - throw common::InvalidValuesException("Invalid object"); + return false; } return filtered_object->isMatchingAttributeRange(m_attribute_name, m_initial_value, diff --git a/src/messaging/MsgCommon/CompositeFilter.cpp b/src/messaging/MsgCommon/CompositeFilter.cpp index fc4d9ce8..6c6212d5 100644 --- a/src/messaging/MsgCommon/CompositeFilter.cpp +++ b/src/messaging/MsgCommon/CompositeFilter.cpp @@ -63,45 +63,11 @@ void CompositeFilter::addFilter(const AbstractFilterPtr& filter) m_filters.push_back(filter); } -//void CompositeFilter::setFilters(const AbstractFilterPtrVector &filters) -//{ -// if (Common::GlobalContextManager::getInstance()->isAliveGlobalContext( -// m_context) && m_js_filters) { -// *m_js_filters = filters; -// } -// m_filters = filters; -//} -// -//JSFilterArray CompositeFilter::getJSFilters(JSContextRef global_ctx) -//{ -// if (!m_context && !global_ctx) { -// LoggerE("Context is not set"); -// throw Common::UnknownException("Context is not set"); -// } -// else if (!m_context && global_ctx) { -// m_context = global_ctx; -// } -// -// if (!Common::GlobalContextManager::getInstance()->isAliveGlobalContext( -// m_context)) { -// LoggerE("Context is not alive"); -// throw Common::UnknownException("Context is not alive"); -// } -// else if (!m_js_filters) { -// m_js_filters = std::shared_ptr(new JSFilterArray( -// m_context)); -// *m_js_filters = m_filters; -// m_filters.clear(); -// } -// return *m_js_filters; -//} - - bool CompositeFilter::isMatching(const FilterableObject* const filtered_object) const { - if(!filtered_object) { + if (!filtered_object) { LoggerE("Invalid object: NULL!"); - throw common::InvalidValuesException("Invalid object"); + return false; } bool composite_result = false; diff --git a/src/messaging/MsgCommon/CompositeFilter.h b/src/messaging/MsgCommon/CompositeFilter.h index e17c0945..dafd0f0c 100644 --- a/src/messaging/MsgCommon/CompositeFilter.h +++ b/src/messaging/MsgCommon/CompositeFilter.h @@ -23,7 +23,6 @@ #define __TIZEN_TIZEN_COMPOSITE_FILTER_H__ #include "AbstractFilter.h" -//#include namespace extension { namespace tizen { @@ -45,17 +44,11 @@ public: void setType(CompositeFilterType type); const AbstractFilterPtrVector& getFilters() const; void addFilter(const AbstractFilterPtr& filter); -// void setFilters(const AbstractFilterPtrVector &filter); -// JSFilterArray getJSFilters(JSContextRef ctx); -// JSContextRef getContext() const; virtual bool isMatching(const FilterableObject* const filtered_object) const; private: CompositeFilterType m_type; AbstractFilterPtrVector m_filters; -// JSContextRef m_context; -// std::shared_ptr m_js_filters; - }; } //Tizen diff --git a/src/messaging/MsgCommon/FilterIterator.cpp b/src/messaging/MsgCommon/FilterIterator.cpp index 2310e7fb..f0c4ac1f 100644 --- a/src/messaging/MsgCommon/FilterIterator.cpp +++ b/src/messaging/MsgCommon/FilterIterator.cpp @@ -28,9 +28,9 @@ FilterIterator::FilterIterator(AbstractFilterPtr filter) : m_root_filter(filter), m_current_state(FIS_NOT_VALID) { - if(!m_root_filter) { - LoggerE("Cannot create FilterIterator for NULL filter"); - throw UnknownException("filter is NULL"); + if (!m_root_filter) { + LoggerE("Trying to create FilterIterator with NULL filter"); + m_root_filter = AbstractFilterPtr(new AbstractFilter()); } goToNext(m_root_filter); diff --git a/src/messaging/conversation_callback_data.cc b/src/messaging/conversation_callback_data.cc index f52d6dc5..e23eb66e 100644 --- a/src/messaging/conversation_callback_data.cc +++ b/src/messaging/conversation_callback_data.cc @@ -89,6 +89,19 @@ void ConversationCallbackData::setError(const std::string& err_name, } } +void ConversationCallbackData::SetError(const common::PlatformResult& error) +{ + // keep only first error in chain + if (!m_is_error) { + m_is_error = true; + picojson::object& obj = m_json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + auto obj_data = picojson::object(); + obj_data[JSON_ERROR_CODE] = picojson::value(static_cast(error.error_code())); + obj_data[JSON_ERROR_MESSAGE] = picojson::value(error.message()); + obj[JSON_DATA] = picojson::value(obj_data); + } +} bool ConversationCallbackData::isError() const { return m_is_error; diff --git a/src/messaging/conversation_callback_data.h b/src/messaging/conversation_callback_data.h index 25ddc28e..235306db 100644 --- a/src/messaging/conversation_callback_data.h +++ b/src/messaging/conversation_callback_data.h @@ -37,6 +37,7 @@ public: void setError(const std::string& err_name, const std::string& err_message); + void SetError(const common::PlatformResult& error); bool isError() const; std::string getErrorName() const; std::string getErrorMessage() const; diff --git a/src/messaging/email_manager.cc b/src/messaging/email_manager.cc index ef63611a..62aef82f 100644 --- a/src/messaging/email_manager.cc +++ b/src/messaging/email_manager.cc @@ -23,6 +23,7 @@ //#include //#include #include "common/logger.h" +#include "common/scope_exit.h" #include #include "common/platform_exception.h" #include @@ -61,6 +62,8 @@ #include #include "MsgCommon/FilterIterator.h" +#include "common/scope_exit.h" + using namespace common; using namespace extension::tizen; @@ -72,75 +75,99 @@ const int ACCOUNT_ID_NOT_INITIALIZED = -1; const std::string FIND_FOLDERS_ATTRIBUTE_ACCOUNTID_NAME = "serviceId"; } //anonymous namespace -EmailManager& EmailManager::getInstance() +EmailManager::EmailManager() : m_is_initialized(false) { LoggerD("Entered"); +} +EmailManager& EmailManager::getInstance() +{ + LoggerD("Entered"); static EmailManager instance; return instance; } -EmailManager::EmailManager() +#define CHECK_ERROR(ret, message) \ + if (ret.IsError()) { \ + LoggerE(message); \ + return ret; \ + } + +PlatformResult EmailManager::InitializeEmailService() { LoggerD("Entered"); - getUniqueOpId(); - const int non_err = EMAIL_ERROR_NONE; + EmailManager& instance = EmailManager::getInstance(); - if(non_err != email_service_begin()){ - LoggerE("Email service failed to begin"); - throw UnknownException("Email service failed to begin"); - } - if(non_err != email_open_db()){ - LoggerE("Email DB failed to open"); - throw UnknownException("Email DB failed to open"); - } + if (!instance.m_is_initialized) { + instance.getUniqueOpId(); + const int non_err = EMAIL_ERROR_NONE; - int slot_size = -1; - vconf_get_int("db/private/email-service/slot_size", &(slot_size)); - if (slot_size > 0) { - m_slot_size = slot_size; - } + if(non_err != email_service_begin()){ + LoggerE("Email service failed to begin"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Email service failed to begin"); + } - m_proxy_sync = std::make_shared( - DBus::Proxy::DBUS_PATH_NETWORK_STATUS, - DBus::Proxy::DBUS_IFACE_NETWORK_STATUS); - if (!m_proxy_sync) { - LoggerE("Sync proxy is null"); - throw UnknownException("Sync proxy is null"); - } - m_proxy_sync->signalSubscribe(); + if(non_err != email_open_db()){ + LoggerE("Email DB failed to open"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Email DB failed to open"); + } - m_proxy_load_body = std::make_shared( - DBus::Proxy::DBUS_PATH_NETWORK_STATUS, - DBus::Proxy::DBUS_IFACE_NETWORK_STATUS); - if (!m_proxy_load_body) { - LoggerE("Load body proxy is null"); - throw UnknownException("Load body proxy is null"); - } - m_proxy_load_body->signalSubscribe(); + int slot_size = -1; + vconf_get_int("db/private/email-service/slot_size", &(slot_size)); + if (slot_size > 0) { + instance.m_slot_size = slot_size; + } -// m_proxy_load_attachment = std::make_shared( -// DBus::Proxy::DBUS_PATH_NETWORK_STATUS, -// DBus::Proxy::DBUS_IFACE_NETWORK_STATUS); -// if (!m_proxy_load_attachment) { -// LoggerE("Load attachment proxy is null"); -// throw Common::UnknownException("Load attachment proxy is null"); -// } -// m_proxy_load_attachment->signalSubscribe(); + PlatformResult ret = DBus::SyncProxy::create(DBus::Proxy::DBUS_PATH_NETWORK_STATUS, + DBus::Proxy::DBUS_IFACE_NETWORK_STATUS, + &instance.m_proxy_sync); + CHECK_ERROR(ret, "create sync proxy failed"); + if (!instance.m_proxy_sync) { + LoggerE("Sync proxy is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Sync proxy is null"); + } + instance.m_proxy_sync->signalSubscribe(); + + ret = DBus::LoadBodyProxy::create(DBus::Proxy::DBUS_PATH_NETWORK_STATUS, + DBus::Proxy::DBUS_IFACE_NETWORK_STATUS, + &instance.m_proxy_load_body); + CHECK_ERROR(ret, "create load body proxy failed"); + if (!instance.m_proxy_load_body) { + LoggerE("Load body proxy is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Load body proxy is null"); + } + instance.m_proxy_load_body->signalSubscribe(); + + // ret = DBus::LoadAttachmentProxy::create(DBus::Proxy::DBUS_PATH_NETWORK_STATUS, + // DBus::Proxy::DBUS_IFACE_NETWORK_STATUS, + // &m_proxy_load_attachment); + // CHECK_ERROR(ret, "create load attachment proxy failed"); + // if (!m_proxy_load_attachment) { + // LoggerE("Load attachment proxy is null"); + // return PlatformResult(ErrorCode::UNKNOWN_ERR, "Load attachment proxy is null"); + // } + // m_proxy_load_attachment->signalSubscribe(); + + ret = DBus::MessageProxy::create(&instance.m_proxy_messageStorage); + CHECK_ERROR(ret, "create message proxy failed"); + if (!instance.m_proxy_messageStorage) { + LoggerE("Message proxy is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Message proxy is null"); + } + instance.m_proxy_messageStorage->signalSubscribe(); - m_proxy_messageStorage = std::make_shared(); - if (!m_proxy_messageStorage) { - LoggerE("Message proxy is null"); - throw UnknownException("Message proxy is null"); - } - m_proxy_messageStorage->signalSubscribe(); + ret = DBus::SendProxy::create(&instance.m_proxy_send); + CHECK_ERROR(ret, "create send proxy failed"); + if (!instance.m_proxy_send) { + LoggerE("Send proxy is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Send proxy is null"); + } + instance.m_proxy_send->signalSubscribe(); - m_proxy_send = std::make_shared(); - if (!m_proxy_send) { - LoggerE("Send proxy is null"); - throw UnknownException("Send proxy is null"); + instance.m_is_initialized = true; } - m_proxy_send->signalSubscribe(); + + return PlatformResult(ErrorCode::NO_ERROR); } EmailManager::~EmailManager() @@ -148,20 +175,20 @@ EmailManager::~EmailManager() LoggerD("Entered"); } -void EmailManager::addDraftMessagePlatform(int account_id, +PlatformResult EmailManager::addDraftMessagePlatform(int account_id, std::shared_ptr message) { LoggerD("Entered"); - addMessagePlatform(account_id, message, EMAIL_MAILBOX_TYPE_DRAFT); + return addMessagePlatform(account_id, message, EMAIL_MAILBOX_TYPE_DRAFT); } -void EmailManager::addOutboxMessagePlatform(int account_id, +PlatformResult EmailManager::addOutboxMessagePlatform(int account_id, std::shared_ptr message) { - addMessagePlatform(account_id, message, EMAIL_MAILBOX_TYPE_OUTBOX); + return addMessagePlatform(account_id, message, EMAIL_MAILBOX_TYPE_OUTBOX); } -void EmailManager::addMessagePlatform(int account_id, +PlatformResult EmailManager::addMessagePlatform(int account_id, std::shared_ptr message, email_mailbox_type_e mailbox_type) { LoggerD("Entered"); @@ -169,7 +196,8 @@ void EmailManager::addMessagePlatform(int account_id, email_mail_data_t* mail_data_final = NULL; int err = EMAIL_ERROR_NONE; - mail_data = Message::convertPlatformEmail(message); + PlatformResult ret = Message::convertPlatformEmail(message, &mail_data); + if (ret.IsError()) return ret; mail_data->account_id = account_id; @@ -182,7 +210,7 @@ void EmailManager::addMessagePlatform(int account_id, if(EMAIL_ERROR_NONE != err) { LoggerE("Failed to free mail data memory"); } - throw UnknownException("Cannot retrieve email account information"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot retrieve email account information"); } LoggerE("FROM %s", account->user_email_address); std::stringstream ss; @@ -205,7 +233,7 @@ void EmailManager::addMessagePlatform(int account_id, if(EMAIL_ERROR_NONE != err) { LoggerE("Failed to free mail data memory"); } - throw UnknownException("Cannot retrieve draft mailbox"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot retrieve draft mailbox"); } else { LoggerD("email_get_mailbox_by_mailbox_type success.\n"); @@ -229,7 +257,7 @@ void EmailManager::addMessagePlatform(int account_id, if (EMAIL_ERROR_NONE != err) { LoggerE("Failed to destroy mailbox"); } - throw UnknownException("Couldn't add message to draft mailbox"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Couldn't add message to draft mailbox"); } else { LoggerD("email_add_mail success.\n"); @@ -241,16 +269,17 @@ void EmailManager::addMessagePlatform(int account_id, message->setMessageStatus(MessageStatus::STATUS_DRAFT); if (message->getHasAttachment()){ - Message::addEmailAttachments(message); + ret = Message::addEmailAttachments(message); + if (ret.IsError()) return ret; } err = email_get_mail_data(message->getId(), &mail_data_final); if(EMAIL_ERROR_NONE != err) { LoggerE("Failed to retrieve added mail data"); - throw UnknownException("Couldn't retrieve added mail data"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Couldn't retrieve added mail data"); } - - message->updateEmailMessage(*mail_data_final); + ret = message->updateEmailMessage(*mail_data_final); + if (ret.IsError()) return ret; err = email_free_mail_data(&mail_data_final,1); if(EMAIL_ERROR_NONE != err) { @@ -266,6 +295,7 @@ void EmailManager::addMessagePlatform(int account_id, if (EMAIL_ERROR_NONE != err) { LoggerE("Failed to destroy mailbox"); } + return PlatformResult(ErrorCode::NO_ERROR); } static gboolean addDraftMessageCompleteCB(void *data) @@ -277,18 +307,17 @@ static gboolean addDraftMessageCompleteCB(void *data) return false; } - try { + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { if (callback->isError()) { LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize() ); callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); } else { LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); picojson::object args; @@ -300,11 +329,8 @@ static gboolean addDraftMessageCompleteCB(void *data) json->serialize() ); } - } catch (const PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); - } catch (...) { - LoggerE("Message add draft failed"); + } else { + LoggerE("Callback id is missing"); callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); } @@ -316,32 +342,27 @@ static gboolean addDraftMessageCompleteCB(void *data) void EmailManager::addDraftMessage(MessageCallbackUserData* callback) { - LoggerD("Entered"); - - if(!callback){ - LoggerE("Callback is null"); - return; - } - - try { - std::lock_guard lock(m_mutex); - std::shared_ptr message = callback->getMessage(); - addDraftMessagePlatform(callback->getAccountId(), message); - } catch (const PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Message add draft failed"); - UnknownException err("Message add draft failed"); - callback->setError(err.name(), err.message()); - } + LoggerD("Entered"); - //Complete task - if (!g_idle_add(addDraftMessageCompleteCB, static_cast(callback))) { - LoggerE("g_idle addition failed"); - delete callback; - callback = NULL; - } + if(!callback){ + LoggerE("Callback is null"); + return; + } + { + std::lock_guard lock(m_mutex); + std::shared_ptr message = callback->getMessage(); + PlatformResult ret = addDraftMessagePlatform(callback->getAccountId(), message); + if (ret.IsError()) { + LoggerE("%d (%s)", ret.error_code(), ret.message().c_str()); + callback->setError(ret); + } + } + //Complete task + if (!g_idle_add(addDraftMessageCompleteCB, static_cast(callback))) { + LoggerE("g_idle addition failed"); + delete callback; + callback = NULL; + } } //**** sending email **** @@ -356,17 +377,16 @@ static gboolean sendEmailCompleteCB(void* data) return false; } - try { + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { if (callback->isError()) { - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize() ); callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); } else { - auto json = callback->getJson(); - picojson::object& obj = json->get(); obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); std::vector recipients; @@ -394,12 +414,8 @@ static gboolean sendEmailCompleteCB(void* data) ); callback->getMessage()->setMessageStatus(MessageStatus::STATUS_SENT); } - } - catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - } - catch (...) { - LoggerE("Unknown error when calling send message callback"); + } else { + LoggerE("Callback id is missing"); } delete callback; @@ -408,74 +424,77 @@ static gboolean sendEmailCompleteCB(void* data) return false; } -void EmailManager::sendMessage(MessageRecipientsCallbackData* callback) +PlatformResult EmailManager::sendMessage(MessageRecipientsCallbackData* callback) { - LoggerD("Entered"); - int err = EMAIL_ERROR_NONE; - email_mail_data_t *mail_data = NULL; + LoggerD("Entered"); - try{ - if(!callback){ - LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } + if (!callback) { + LoggerE("Callback is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Callback is null"); + } - std::shared_ptr message = callback->getMessage(); - if(!message) { - LoggerE("Message is null"); - throw common::UnknownException("Message is null"); - } + int err = EMAIL_ERROR_NONE; + email_mail_data_t *mail_data = NULL; - if(!(message->is_id_set())) { - addOutboxMessagePlatform(callback->getAccountId(),message); - } + PlatformResult platform_result(ErrorCode::NO_ERROR); - err = email_get_mail_data(message->getId(),&mail_data); - if(EMAIL_ERROR_NONE != err) { - LoggerE("email_get_mail_data failed. [%d]\n",err); - throw common::UnknownException("Failed to get platform email structure"); - } + std::shared_ptr message = callback->getMessage(); - LoggerD("email_get_mail_data success.\n"); + if (message) { + if (!(message->is_id_set())) { + platform_result = addOutboxMessagePlatform(callback->getAccountId(), message); + if (platform_result.IsError()) return platform_result; + } - //Sending EMAIL - mail_data->save_status = EMAIL_MAIL_STATUS_SENDING; + err = email_get_mail_data(message->getId(),&mail_data); - int req_id = 0; - err = email_send_mail(mail_data->mail_id, &req_id); - if (EMAIL_ERROR_NONE != err) { - LoggerE("Failed to send message %d", err); - throw common::UnknownException("Failed to send message"); - } + if (EMAIL_ERROR_NONE != err) { + LoggerE("email_get_mail_data failed. [%d]\n", err); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get platform email structure"); + } else { + LoggerD("email_get_mail_data success.\n"); + + // Sending EMAIL + mail_data->save_status = EMAIL_MAIL_STATUS_SENDING; + + int req_id = 0; + err = email_send_mail(mail_data->mail_id, &req_id); + + if (EMAIL_ERROR_NONE != err) { + LoggerE("Failed to send message %d", err); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to send message"); + } else { LoggerD("req_id: %d", req_id); callback->getMessage()->setMessageStatus(MessageStatus::STATUS_SENDING); m_sendRequests[req_id] = callback; + } + } + } else { + LoggerE("Message is null"); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Message is null"); + } - } catch (const common::PlatformException& ex) { - LoggerE("%s (%s)", (ex.name()).c_str(), (ex.message()).c_str()); - callback->setError(ex.name(), ex.message()); - if (!g_idle_add(sendEmailCompleteCB, static_cast(callback))) { - LoggerE("g_idle addition failed"); - delete callback; - callback = NULL; - } - }catch (...) { - LoggerE("Message send failed"); - common::UnknownException ex("Message send failed"); - callback->setError(ex.name(), ex.message()); - if (!g_idle_add(sendEmailCompleteCB, static_cast(callback))) { - LoggerE("g_idle addition failed"); - delete callback; - callback = NULL; - } + if (!platform_result) { + LoggerE("Message send failed"); + + callback->setError(platform_result); + + if (!g_idle_add(sendEmailCompleteCB, static_cast(callback))) { + LoggerE("g_idle addition failed"); + delete callback; + callback = NULL; } + } - err = email_free_mail_data(&mail_data,1); - if(EMAIL_ERROR_NONE != err) { - LoggerE("Failed to free mail data memory"); + if (mail_data) { + err = email_free_mail_data(&mail_data, 1); + + if (EMAIL_ERROR_NONE != err) { + LoggerE("Failed to free mail data memory"); } + } - return; + return platform_result; } void EmailManager::sendStatusCallback(int mail_id, @@ -591,117 +610,123 @@ void EmailManager::loadMessageBody(MessageBodyCallbackData* callback) callback->setOperationHandle(op_handle); } -void EmailManager::loadMessageAttachment(MessageAttachmentCallbackData* callback) +PlatformResult EmailManager::loadMessageAttachment(MessageAttachmentCallbackData* callback) { - LoggerD("Entered"); - if(!callback) { - LoggerE("Callback is null"); - throw common::InvalidValuesException("Callback is null"); - } - if(!callback->getMessageAttachment()) { - LoggerE("Callback's message attachment is null"); - throw common::InvalidValuesException("Callback's message attachment is null"); - } - - std::shared_ptr msgAttachment = callback->getMessageAttachment(); - LoggerD("attachmentId:%d mailId:%d", msgAttachment->getId(), - msgAttachment->getMessageId()); - - struct ScopedEmailMailData { - ScopedEmailMailData() : data(NULL) { } - ~ScopedEmailMailData() { EmailManager::freeMessage(data); } - email_mail_data_t* data; - } mail_data_holder; - - mail_data_holder.data = EmailManager::loadMessage(msgAttachment->getMessageId()); - if(!mail_data_holder.data) { - std::stringstream err_ss; - err_ss << "Couldn't get email_mail_data_t for messageId:" - << msgAttachment->getMessageId(); - LoggerE("%s",err_ss.str().c_str()); - throw common::UnknownException(err_ss.str().c_str()); - } - - AttachmentPtrVector attachments = Message::convertEmailToMessageAttachment( - *mail_data_holder.data); - LoggerD("Mail:%d contain:%d attachments", msgAttachment->getMessageId(), - attachments.size()); - - AttachmentPtrVector::iterator it = attachments.begin(); - int attachmentIndex = -1; - for(int i = 0; it != attachments.end(); ++i, ++it) { - if((*it)->getId() == msgAttachment->getId()) { - attachmentIndex = i; - break; - } - } + LoggerD("Entered"); - if(attachmentIndex < 0) { - std::stringstream err_ss; - err_ss << "Attachment with id:" << msgAttachment->getId() << "not found"; - LoggerE("%s",err_ss.str().c_str()); - throw common::UnknownException(err_ss.str().c_str()); - } + if (!callback) { + LoggerE("Callback is null"); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Callback is null"); + } - LoggerD("Attachment with id:%d is located at index:%d", msgAttachment->getId(), - attachmentIndex); + if (!callback->getMessageAttachment()) { + LoggerE("Callback's message attachment is null"); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Callback's message attachment is null"); + } - int op_handle = -1; - const int nth = attachmentIndex + 1; //in documentation: the minimum number is "1" - callback->setNth(nth); + std::shared_ptr msgAttachment = callback->getMessageAttachment(); + LoggerD("attachmentId: [%d] mailId: [%d]", msgAttachment->getId(), + msgAttachment->getMessageId()); - int err = email_download_attachment(msgAttachment->getMessageId(), nth, &op_handle); - if (EMAIL_ERROR_NONE != err) { - std::stringstream err_ss; - err_ss << "Download email attachment failed with error: " << err; - LoggerE("%s",err_ss.str().c_str()); - throw common::UnknownException(err_ss.str().c_str()); - } else { - LoggerD("email_download_attachment returned handle:%d",op_handle); - callback->setOperationHandle(op_handle); - m_proxy_load_attachment->addCallback(callback); + email_mail_data_t* mail_data = EmailManager::loadMessage(msgAttachment->getMessageId()); + + SCOPE_EXIT { + EmailManager::freeMessage(mail_data); + }; + + if (!mail_data) { + LoggerE("Couldn't get email_mail_data_t for messageId: %d", msgAttachment->getMessageId()); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Couldn't load message."); + } + + AttachmentPtrVector attachments; + auto platform_result = Message::convertEmailToMessageAttachment(*mail_data, &attachments); + + if (!platform_result) { + return platform_result; + } + + LoggerD("Mail: [%d] contains: [%d] attachments", + msgAttachment->getMessageId(), attachments.size()); + + auto it = attachments.begin(); + int attachmentIndex = -1; + for (int i = 0; it != attachments.end(); ++i, ++it) { + if ((*it)->getId() == msgAttachment->getId()) { + attachmentIndex = i; + break; } + } + + if (attachmentIndex < 0) { + LoggerE("Attachment with id: %d not found", msgAttachment->getId()); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Couldn't find attachment."); + } + + LoggerD("Attachment with id: [%d] is located at index: [%d]", + msgAttachment->getId(), attachmentIndex); + + int op_handle = -1; + const int nth = attachmentIndex + 1; //in documentation: the minimum number is "1" + callback->setNth(nth); + + int err = email_download_attachment(msgAttachment->getMessageId(), nth, &op_handle); + + if (EMAIL_ERROR_NONE != err) { + LoggerE("Download email attachment failed with error: %d", err); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to load attachment."); + } else { + LoggerD("email_download_attachment returned handle: [%d]", op_handle); + callback->setOperationHandle(op_handle); + m_proxy_load_attachment->addCallback(callback); + return PlatformResult(ErrorCode::NO_ERROR); + } } //#################################### sync: ################################### void EmailManager::sync(void* data) { - LoggerD("Entered"); - SyncCallbackData* callback = static_cast(data); - if(!callback){ - LoggerE("Callback is null"); - return; - } - long op_id = callback->getOpId(); - m_proxy_sync->addCallback(op_id, callback); + LoggerD("Entered"); - int err = EMAIL_ERROR_NONE; - int limit = callback->getLimit(); - int slot_size = -1; - int account_id = callback->getAccountId(); + SyncCallbackData* callback = static_cast(data); - if (limit < 0) { - slot_size = m_slot_size; - } - else { - slot_size = limit; - } + if (!callback) { + LoggerE("Callback is null"); + return; + } - err = email_set_mail_slot_size(0, 0, slot_size); - if(EMAIL_ERROR_NONE != err){ - LoggerE("Email set slot size failed, %d", err); - m_proxy_sync->removeCallback(op_id); - return; - } + long op_id = callback->getOpId(); + m_proxy_sync->addCallback(op_id, callback); - int op_handle = -1; - err = email_sync_header(account_id, 0, &op_handle); - if(EMAIL_ERROR_NONE != err){ - LoggerE("Email sync header failed, %d", err); - m_proxy_sync->removeCallback(op_id); - } + int err = EMAIL_ERROR_NONE; + int limit = callback->getLimit(); + int slot_size = -1; + int account_id = callback->getAccountId(); + + if (limit < 0) { + slot_size = m_slot_size; + } else { + slot_size = limit; + } + + err = email_set_mail_slot_size(0, 0, slot_size); + + if (EMAIL_ERROR_NONE != err) { + LoggerE("Email set slot size failed, %d", err); + m_proxy_sync->removeCallback(op_id); + return; + } + + int op_handle = -1; + err = email_sync_header(account_id, 0, &op_handle); + + if (EMAIL_ERROR_NONE != err) { + LoggerE("Email sync header failed, %d", err); + m_proxy_sync->removeCallback(op_id); + } else { callback->setOperationHandle(op_handle); + } } //#################################### ^sync ################################### @@ -710,76 +735,71 @@ void EmailManager::sync(void* data) void EmailManager::syncFolder(SyncFolderCallbackData* callback) { - LoggerD("Entered"); - if(!callback){ - LoggerE("Callback is null"); - return; - } + LoggerD("Entered"); - const long op_id = callback->getOpId(); - m_proxy_sync->addCallback(op_id, callback); + if (!callback) { + LoggerE("Callback is null"); + return; + } - if(!callback->getMessageFolder()) - { - LoggerE("Callback's messageFolder is null"); - m_proxy_sync->removeCallback(op_id); - return; - } + const long op_id = callback->getOpId(); + m_proxy_sync->addCallback(op_id, callback); - int err = EMAIL_ERROR_NONE; + if (!callback->getMessageFolder()) { + LoggerE("Callback's messageFolder is null"); + m_proxy_sync->removeCallback(op_id); + return; + } - email_mailbox_t* mailbox = NULL; + int err = EMAIL_ERROR_NONE; - const std::string folder_id_str = callback->getMessageFolder()->getId(); - int folder_id = 0; - std::istringstream(folder_id_str) >> folder_id; + email_mailbox_t* mailbox = NULL; - err = email_get_mailbox_by_mailbox_id(folder_id, &mailbox); - if (EMAIL_ERROR_NONE != err || NULL == mailbox) { - LoggerE("Couldn't get mailbox, error code: %d", err); - m_proxy_sync->removeCallback(op_id); - return; - } + const std::string folder_id_str = callback->getMessageFolder()->getId(); + int folder_id = 0; + std::istringstream(folder_id_str) >> folder_id; - try { - const int limit = callback->getLimit(); - int slot_size = -1; + err = email_get_mailbox_by_mailbox_id(folder_id, &mailbox); - if (limit < 0) { - slot_size = m_slot_size; - } - else { - slot_size = limit; - } + if (EMAIL_ERROR_NONE != err || NULL == mailbox) { + LoggerE("Couldn't get mailbox, error code: %d", err); + m_proxy_sync->removeCallback(op_id); + return; + } - err = email_set_mail_slot_size(0, 0, slot_size); - if(EMAIL_ERROR_NONE != err){ - LoggerE("Email set slot size failed, %d", err); - throw UnknownException("Email set slot size failed"); - } + const int limit = callback->getLimit(); + int slot_size = -1; - int op_handle = -1; - const int account_id = callback->getAccountId(); - err = email_sync_header(account_id, mailbox->mailbox_id, &op_handle); - if(EMAIL_ERROR_NONE != err) { - LoggerE("Email sync header failed, %d", err); - m_proxy_sync->removeCallback(op_id); - throw UnknownException("Email sync header failed"); - } - callback->setOperationHandle(op_handle); - } - catch (const PlatformException& e) { - LoggerE("Exception in syncFolder"); + if (limit < 0) { + slot_size = m_slot_size; + } else { + slot_size = limit; + } + + err = email_set_mail_slot_size(0, 0, slot_size); + if (EMAIL_ERROR_NONE != err) { + LoggerE("Email set slot size failed, %d", err); + } else { + int op_handle = -1; + const int account_id = callback->getAccountId(); + + err = email_sync_header(account_id, mailbox->mailbox_id, &op_handle); + + if (EMAIL_ERROR_NONE != err) { + LoggerE("Email sync header failed, %d", err); + m_proxy_sync->removeCallback(op_id); + } else { + callback->setOperationHandle(op_handle); } + } - if (NULL != mailbox) - { - err = email_free_mailbox(&mailbox , 1); - if (EMAIL_ERROR_NONE != err) { - LoggerD("Failed to email_free_mailbox - err:%d ", err); - } - mailbox = NULL; + if (NULL != mailbox) { + err = email_free_mailbox(&mailbox, 1); + if (EMAIL_ERROR_NONE != err) { + LoggerD("Failed to email_free_mailbox - err:%d ", err); } + mailbox = NULL; + } } //#################################### ^syncFolder ############################# @@ -788,75 +808,70 @@ void EmailManager::syncFolder(SyncFolderCallbackData* callback) void EmailManager::stopSync(long op_id) { - LoggerD("Entered"); - SyncCallbackData* callback = NULL; - try { - callback = dynamic_cast( - m_proxy_sync->getCallback(op_id)); - } - catch (const PlatformException& e) { - LoggerE("Could not get callback"); - } - if(!callback){ - LoggerE("Callback is null"); - return; - } + LoggerD("Entered"); - int err = EMAIL_ERROR_NONE; - err = email_cancel_job(callback->getAccountId(), callback->getOperationHandle(), - EMAIL_CANCELED_BY_USER); - if(EMAIL_ERROR_NONE != err){ - LoggerE("Email cancel job failed, %d", err); - } + SyncCallbackData* callback = static_cast(m_proxy_sync->getCallback(op_id)); - std::shared_ptr response = callback->getJson(); - picojson::object& obj = response->get(); - AbortException error("Sync aborted by user"); - callback->setError(error.name(), error.message()); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - response->serialize() - ); + if (!callback) { + LoggerE("Callback is null"); + return; + } + + int err = EMAIL_ERROR_NONE; + err = email_cancel_job(callback->getAccountId(), + callback->getOperationHandle(), + EMAIL_CANCELED_BY_USER); + + if (EMAIL_ERROR_NONE != err) { + LoggerE("Email cancel job failed, %d", err); + } + + std::shared_ptr response = callback->getJson(); + picojson::object& obj = response->get(); + + if (response->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + callback->setError(PlatformResult(ErrorCode::ABORT_ERR, "Sync aborted by user")); + + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + response->serialize()); m_proxy_sync->removeCallback(op_id); + } else { + LoggerE("Callback id is missing"); + } } //################################## ^stopSync ################################# void removeEmailCompleteCB(MessagesCallbackUserData* callback) { - LoggerD("Entered"); - if (!callback) { - LoggerE("Callback is null"); - return; - } - - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); + LoggerD("Entered"); + if (!callback) { + LoggerE("Callback is null"); + return; + } + + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); + } else { + LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const PlatformException& err) { - LoggerE("Error while calling removeEmail callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Unknown error when calling removeEmail callback."); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); } + } else { + LoggerE("Callback id is missing"); + } - delete callback; - callback = NULL; + delete callback; + callback = NULL; } EmailManager::DeleteReqVector::iterator EmailManager::getDeleteRequest( @@ -910,59 +925,122 @@ void EmailManager::removeStatusCallback(const std::vector &ids, } } +PlatformResult EmailManager::RemoveMessagesPlatform(MessagesCallbackUserData* callback) +{ + int error; + email_mail_data_t *mail = NULL; + + std::lock_guard lock(m_mutex); + std::vector> messages = callback->getMessages(); + MessageType type = callback->getMessageServiceType(); + for(auto it = messages.begin() ; it != messages.end(); ++it) { + if((*it)->getType() != type) { + LoggerE("Invalid message type"); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Error while deleting email"); + } + } + for (auto it = messages.begin() ; it != messages.end(); ++it) { + error = email_get_mail_data((*it)->getId(), &mail); + if (EMAIL_ERROR_NONE != error) { + LoggerE("Couldn't retrieve mail data"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while deleting mail"); + } + + //This task (_EMAIL_API_DELETE_MAIL) is for async + error = email_delete_mail(mail->mailbox_id, &mail->mail_id, 1, 0); + if (EMAIL_ERROR_NONE != error) { + email_free_mail_data(&mail, 1); + LoggerE("Error while deleting mail"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while deleting mail"); + } + email_free_mail_data(&mail, 1); + } + //store delete request and wait for dbus response + DeleteReq request; + request.callback = callback; + request.messagesDeleted = 0; + m_deleteRequests.push_back(request); + + return PlatformResult(ErrorCode::NO_ERROR); +} + void EmailManager::removeMessages(MessagesCallbackUserData* callback) { - LoggerD("Entered"); + LoggerD("Entered"); - if (!callback){ - LoggerE("Callback is null"); - return; + if (!callback){ + LoggerE("Callback is null"); + return; + } + + PlatformResult ret = RemoveMessagesPlatform(callback); + if (ret.IsError()) { + LoggerE("%d (%s)", ret.error_code(), (ret.message()).c_str()); + callback->SetError(ret); + removeEmailCompleteCB(callback); + } +} + +PlatformResult EmailManager::UpdateMessagesPlatform(MessagesCallbackUserData* callback) { + int error; + email_mail_data_t *mail = NULL; + SCOPE_EXIT { + if (mail) { + email_free_mail_data(&mail, 1); + mail = NULL; } + }; - int error; - email_mail_data_t *mail = NULL; + std::lock_guard lock(m_mutex); + std::vector> messages = callback->getMessages(); + MessageType type = callback->getMessageServiceType(); + for (auto it = messages.begin() ; it != messages.end(); ++it) { + if ((*it)->getType() != type) { + LoggerE("Invalid message type"); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Error while updating message"); + } + } + for (auto it = messages.begin() ; it != messages.end(); ++it) { - try { - std::lock_guard lock(m_mutex); - std::vector> messages = callback->getMessages(); - MessageType type = callback->getMessageServiceType(); - for(auto it = messages.begin() ; it != messages.end(); ++it) { - if((*it)->getType() != type) { - LoggerE("Invalid message type"); - throw TypeMismatchException("Error while deleting email"); - } - } - for (auto it = messages.begin() ; it != messages.end(); ++it) { - error = email_get_mail_data((*it)->getId(), &mail); - if (EMAIL_ERROR_NONE != error) { - LoggerE("Couldn't retrieve mail data"); - throw UnknownException("Error while deleting mail"); - } + PlatformResult ret = Message::convertPlatformEmail((*it), &mail); + if (ret.IsError()) return ret; - //This task (_EMAIL_API_DELETE_MAIL) is for async - error = email_delete_mail(mail->mailbox_id, &mail->mail_id, 1, 0); - if (EMAIL_ERROR_NONE != error) { - email_free_mail_data(&mail, 1); - LoggerE("Error while deleting mail"); - throw UnknownException("Error while deleting mail"); - } - email_free_mail_data(&mail, 1); - } - //store delete request and wait for dbus response - DeleteReq request; - request.callback = callback; - request.messagesDeleted = 0; - m_deleteRequests.push_back(request); - } catch (const PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - removeEmailCompleteCB(callback); - } catch (...) { - LoggerE("Messages remove failed"); - UnknownException e("Messages remove failed"); - callback->setError(e.name(), e.message()); - removeEmailCompleteCB(callback); - } + if((*it)->getHasAttachment()) + { + LoggerD("Message has attachments. Workaround need to be used."); + //Update of mail on server using function email_update_mail() is not possible. + //Attachment is updated only locally (can't be later loaded from server), + //so use of workaround is needed: + //1. add new mail + //2. delete old mail + + //adding message again after changes + PlatformResult ret = addDraftMessagePlatform(mail->account_id, (*it)); + if (ret.IsError()) { + return ret; + } + LoggerD("mail added - new id = [%d]\n", (*it)->getId()); + + //storing old message id + (*it)->setOldId(mail->mail_id); + //deleting old mail + LoggerD("mail deleted = [%d]\n", mail->mail_id); + error = email_delete_mail(mail->mailbox_id,&mail->mail_id,1,1); + if (EMAIL_ERROR_NONE != error) { + LoggerE("Error while deleting old mail on update: %d", error); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Error while deleting old mail on update"); + } + } else { + LoggerD("There are no attachments, updating only email data."); + error = email_update_mail(mail, NULL, 0, NULL, 0); + if (EMAIL_ERROR_NONE != error) { + LoggerE("Error while updating mail"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while updating mail"); + } + } + } + return PlatformResult(ErrorCode::NO_ERROR); } void EmailManager::updateMessages(MessagesCallbackUserData* callback) @@ -974,183 +1052,143 @@ void EmailManager::updateMessages(MessagesCallbackUserData* callback) return; } - int error; - email_mail_data_t *mail = NULL; - - try { - std::lock_guard lock(m_mutex); - std::vector> messages = callback->getMessages(); - MessageType type = callback->getMessageServiceType(); - for (auto it = messages.begin() ; it != messages.end(); ++it) { - if ((*it)->getType() != type) { - LoggerE("Invalid message type"); - throw TypeMismatchException("Error while updating message"); - } - } - for (auto it = messages.begin() ; it != messages.end(); ++it) { - - mail = Message::convertPlatformEmail((*it)); - - if((*it)->getHasAttachment()) - { - LoggerD("Message has attachments. Workaround need to be used."); - //Update of mail on server using function email_update_mail() is not possible. - //Attachment is updated only locally (can't be later loaded from server), - //so use of workaround is needed: - //1. add new mail - //2. delete old mail - - //adding message again after changes - addDraftMessagePlatform(mail->account_id, (*it)); - LoggerD("mail added - new id = [%d]\n", (*it)->getId()); - - //storing old message id - (*it)->setOldId(mail->mail_id); - //deleting old mail - LoggerD("mail deleted = [%d]\n", mail->mail_id); - error = email_delete_mail(mail->mailbox_id,&mail->mail_id,1,1); - if (EMAIL_ERROR_NONE != error) { - email_free_mail_data(&mail, 1); - LoggerE("Error while deleting old mail on update: %d", error); - throw UnknownException("Error while deleting old mail on update"); - } - } else { - LoggerD("There are no attachments, updating only email data."); - error = email_update_mail(mail, NULL, 0, NULL, 0); - if (EMAIL_ERROR_NONE != error) { - email_free_mail_data(&mail, 1); - LoggerE("Error while updating mail"); - throw UnknownException("Error while updating mail"); - } - } - - email_free_mail_data(&mail, 1); - } - } catch (const PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Messages update failed"); - UnknownException ex("Messages update failed"); - callback->setError(ex.name(), ex.message()); + PlatformResult ret = UpdateMessagesPlatform(callback); + if (ret.IsError()) { + LoggerE("%d (%s)", ret.error_code(), (ret.message()).c_str()); + callback->SetError(ret); } - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } else { + LoggerD("Calling success callback"); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - picojson::array array; - auto messages = callback->getMessages(); - for (int i = 0 ; i < messages.size(); ++i) { - array.push_back(MessagingUtil::messageToJson(messages[i])); - } - obj[JSON_DATA] = picojson::value(array); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); + picojson::array array; + auto messages = callback->getMessages(); + for (int i = 0 ; i < messages.size(); ++i) { + array.push_back(MessagingUtil::messageToJson(messages[i])); } - } catch (const PlatformException& err) { - LoggerE("Error while calling updateEmail callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Unknown error when calling updateEmail callback."); - } + obj[JSON_DATA] = picojson::value(array); + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); + } + } else { + LoggerE("Callback id is missing"); + } delete callback; callback = NULL; } -void EmailManager::findMessages(FindMsgCallbackUserData* callback) +PlatformResult EmailManager::FindMessagesPlatform(FindMsgCallbackUserData* callback) { - LoggerD("Entered"); - - if(!callback){ - LoggerE("Callback is null"); - return; - } - - email_mail_data_t* mailList = NULL; - int mailListCount = 0; - try { - std::lock_guard lock(m_mutex); - std::pair emails = - MessagingDatabaseManager::getInstance().findEmails(callback); - mailListCount = emails.first; - LoggerD("Found %d mails", mailListCount); - - mailList = emails.second; - email_mail_data_t* nth_email = mailList; - - for (int i = 0; i < mailListCount; ++i) { - std::shared_ptr email = - Message::convertPlatformEmailToObject(*nth_email); - callback->addMessage(email); - nth_email++; - } - } catch (const PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Message find failed"); - UnknownException err("Message find failed"); - callback->setError(err.name(), err.message()); - } + email_mail_data_t* mailList = NULL; + int mailListCount = 0; + SCOPE_EXIT { if (mailListCount > 0 && mailList != NULL) { - if (EMAIL_ERROR_NONE != email_free_mail_data(&mailList, mailListCount)) { - LoggerW("Failed to free mailList"); - } - } - - //Complete task - LoggerD("callback: %p error: %d messages.size() = %d", callback, callback->isError(), - callback->getMessages().size()); + if (EMAIL_ERROR_NONE != email_free_mail_data(&mailList, mailListCount)) { + LoggerW("Failed to free mailList"); + } + } + }; + + std::lock_guard lock(m_mutex); + std::pair emails; + PlatformResult ret = MessagingDatabaseManager::getInstance().findEmails(callback, &emails); + if (ret.IsError()) return ret; + mailListCount = emails.first; + LoggerD("Found %d mails", mailListCount); + + mailList = emails.second; + email_mail_data_t* nth_email = mailList; + + for (int i = 0; i < mailListCount; ++i) { + std::shared_ptr email; + ret = Message::convertPlatformEmailToObject(*nth_email, &email); + if (ret.IsError()) return ret; + callback->addMessage(email); + nth_email++; + } + return PlatformResult(ErrorCode::NO_ERROR); +} - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - - std::vector response; - auto messages = callback->getMessages(); - std::for_each(messages.begin(), messages.end(), [&response](MessagePtr &message){ - response.push_back(MessagingUtil::messageToJson(message)); - }); - obj[JSON_DATA] = picojson::value(response); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); +void EmailManager::findMessages(FindMsgCallbackUserData* callback) +{ + LoggerD("Entered"); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const PlatformException& err) { - LoggerE("Error while calling findMessages callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Failed to call findMessages callback."); - } + if(!callback){ + LoggerE("Callback is null"); + return; + } + + PlatformResult ret = FindMessagesPlatform(callback); + if (ret.IsError()) { + LoggerE("%d (%s)", ret.error_code(), (ret.message()).c_str()); + callback->SetError(ret); + } + + //Complete task + LoggerD("callback: %p error: %d messages.size() = %d", callback, callback->isError(), + callback->getMessages().size()); + + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve( obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } else { + LoggerD("Calling success callback"); + std::vector response; + auto messages = callback->getMessages(); + std::for_each(messages.begin(), messages.end(), [&response](MessagePtr &message){ + response.push_back(MessagingUtil::messageToJson(message)); + }); + obj[JSON_DATA] = picojson::value(response); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } + } else { + LoggerE("Failed to call findMessages callback."); + } + + delete callback; + callback = NULL; +} - delete callback; - callback = NULL; +PlatformResult EmailManager::FindConversationsPlatform(ConversationCallbackData* callback) +{ + int convListCount = 0; + + std::lock_guard lock(m_mutex); + std::vector conversationsInfo; + PlatformResult ret = MessagingDatabaseManager::getInstance(). + findEmailConversations(callback, &conversationsInfo); + if (ret.IsError()) return ret; + + convListCount = conversationsInfo.size(); + LoggerD("Found %d conversations", convListCount); + + for (int i = 0; i < convListCount; ++i) { + std::shared_ptr conversation; + PlatformResult ret = MessageConversation::convertEmailConversationToObject( + conversationsInfo.at(i).id, &conversation); + conversation->setUnreadMessages(conversationsInfo.at(i).unreadMessages); + callback->addConversation(conversation); + } + + return PlatformResult(ErrorCode::NO_ERROR); } void EmailManager::findConversations(ConversationCallbackData* callback) @@ -1163,65 +1201,42 @@ void EmailManager::findConversations(ConversationCallbackData* callback) } int convListCount = 0; - try { - std::lock_guard lock(m_mutex); - std::vector conversationsInfo = - MessagingDatabaseManager::getInstance().findEmailConversations(callback); - convListCount = conversationsInfo.size(); - LoggerD("Found %d conversations", convListCount); - - for (int i = 0; i < convListCount; ++i) { - std::shared_ptr conversation = - MessageConversation::convertEmailConversationToObject(conversationsInfo.at(i).id); - conversation->setUnreadMessages(conversationsInfo.at(i).unreadMessages); - callback->addConversation(conversation); - } - - } catch (const PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Conversation find failed"); - UnknownException ex("Conversation find failed"); - callback->setError(ex.name(), ex.message()); + PlatformResult ret = FindConversationsPlatform(callback); + if (ret.IsError()) { + LoggerE("%d (%s)", ret.error_code(), (ret.message()).c_str()); + callback->SetError(ret); } //Complete task LoggerD("callback: %p error:%d conversations.size()=%d", callback, callback->isError(), callback->getConversations().size()); - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - - std::vector response; - auto messages = callback->getConversations(); - std::for_each(messages.begin(), messages.end(), - [&response](std::shared_ptr &conversation) { - response.push_back(MessagingUtil::conversationToJson(conversation)); - } - ); - obj[JSON_DATA] = picojson::value(response); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } else { + LoggerD("Calling success callback"); + + std::vector response; + auto messages = callback->getConversations(); + std::for_each(messages.begin(), messages.end(), + [&response](std::shared_ptr &conversation) { + response.push_back(MessagingUtil::conversationToJson(conversation)); } - } catch (const PlatformException& err) { - LoggerE("Error while calling findConversations callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Failed to call findConversations callback."); + ); + obj[JSON_DATA] = picojson::value(response); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); + } + } else { + LoggerE("Failed to call findConversations callback."); } delete callback; @@ -1238,137 +1253,178 @@ long EmailManager::getUniqueOpId() return op_id++; } -void EmailManager::findFolders(FoldersCallbackData* callback) +PlatformResult EmailManager::FindFoldersPlatform(FoldersCallbackData* callback) { - LoggerD("Entered"); + int ret = EMAIL_ERROR_UNKNOWN; + int account_id = ACCOUNT_ID_NOT_INITIALIZED; + email_mailbox_t* mailboxes = NULL; + email_mailbox_t* nth_mailbox = NULL; + int mailboxes_count; - if (!callback){ - LoggerE("Callback is null"); - return; - } - - int ret = EMAIL_ERROR_UNKNOWN; - int account_id = ACCOUNT_ID_NOT_INITIALIZED; - email_mailbox_t* mailboxes = NULL; - email_mailbox_t* nth_mailbox = NULL; - int mailboxes_count; - - try { - std::lock_guard lock(m_mutex); - - tizen::AbstractFilterPtr filter = callback->getFilter(); - if (!filter) { - LoggerE("Filter not provided"); - throw UnknownException("Filter not provided"); + SCOPE_EXIT { + if (mailboxes != NULL) { + if (EMAIL_ERROR_NONE != email_free_mailbox(&mailboxes, + mailboxes_count)) { + LoggerW("Free mailboxes failed: %d", ret); + } + } + }; + + std::lock_guard lock(m_mutex); + + tizen::AbstractFilterPtr filter = callback->getFilter(); + if (!filter) { + LoggerE("Filter not provided"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Filter not provided"); + } + + for(FilterIterator it(filter); false == it.isEnd(); it++) { + + if (FIS_COMPOSITE_START == it.getState()) { + CompositeFilterPtr cf = castToCompositeFilter((*it)); + if(cf && INTERSECTION != cf->getType()) { + LoggerE("[ERROR] >>> invalid Filter type: %d", cf->getType()); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Invalid Filter Type"); + } + } + else if (FIS_ATTRIBUTE_FILTER == it.getState()) { + AttributeFilterPtr attrf = castToAttributeFilter((*it)); + if (attrf) { + const std::string attr_name = attrf->getAttributeName(); + if (FIND_FOLDERS_ATTRIBUTE_ACCOUNTID_NAME == attr_name) { + account_id = static_cast(attrf->getMatchValue()->toLong()); + } else { + LoggerE("The attribute name: %s is invalid", attr_name.c_str()); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, + "The attribute name is invalid"); } + } + } + } - for(FilterIterator it(filter); false == it.isEnd(); it++) { + LoggerD("Listing folders for account ID: %d", account_id); + if (account_id > 0) { + ret = email_get_mailbox_list(account_id, + -1, + &mailboxes, + &mailboxes_count); + if (EMAIL_ERROR_NONE != ret || !mailboxes) { + LoggerE("Cannot get folders: %d", ret); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Platform error, cannot get folders"); + } - if(FIS_COMPOSITE_START == it.getState()) { - CompositeFilterPtr cf = castToCompositeFilter((*it)); - if(cf && INTERSECTION != cf->getType()) { - LoggerE("[ERROR] >>> invalid Filter type: %d", cf->getType()); - throw TypeMismatchException("Invalid Filter Type"); - } - } - else if(FIS_ATTRIBUTE_FILTER == it.getState()) { - AttributeFilterPtr attrf = castToAttributeFilter((*it)); - if(attrf) { - const std::string attr_name = attrf->getAttributeName(); - if (FIND_FOLDERS_ATTRIBUTE_ACCOUNTID_NAME == attr_name) { - account_id = static_cast(attrf->getMatchValue()->toLong()); - } else { - LoggerE("The attribute name: %s is invalid", attr_name.c_str()); - throw InvalidValuesException("The attribute name is invalid"); - } - } - } - } + if (mailboxes_count <= 0) { + LoggerD("Empty mailboxes"); + } + else { + LoggerD("Founded mailboxes: %d", mailboxes_count); + + nth_mailbox = mailboxes; + for (int i = 0; i < mailboxes_count; ++i) { + std::shared_ptr fd; + fd = std::make_shared(*nth_mailbox); + callback->addFolder(fd); + nth_mailbox++; + } + } + } + return PlatformResult(ErrorCode::NO_ERROR); +} - LoggerD("Listing folders for account ID: %d", account_id); - if (account_id > 0) { - ret = email_get_mailbox_list(account_id, - -1, - &mailboxes, - &mailboxes_count); - if (EMAIL_ERROR_NONE != ret || !mailboxes) { - LoggerE("Cannot get folders: %d", ret); - throw UnknownException("Platform error, cannot get folders"); - } +void EmailManager::findFolders(FoldersCallbackData* callback) +{ + LoggerD("Entered"); - if (mailboxes_count <= 0) { - LoggerD("Empty mailboxes"); - } - else { - LoggerD("Founded mailboxes: %d", mailboxes_count); - - nth_mailbox = mailboxes; - for (int i = 0; i < mailboxes_count; ++i) { - std::shared_ptr fd; - fd = std::make_shared(*nth_mailbox); - callback->addFolder(fd); - nth_mailbox++; - } - } - } - } catch (const PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Messages update failed"); - UnknownException ex("Messages update failed"); - callback->setError(ex.name(), ex.message()); + if (!callback){ + LoggerE("Callback is null"); + return; } - if (mailboxes != NULL) { - if (EMAIL_ERROR_NONE != email_free_mailbox(&mailboxes, - mailboxes_count)) { - LoggerW("Free mailboxes failed: %d", ret); - } + PlatformResult ret = FindFoldersPlatform(callback); + if (ret.IsError()) { + LoggerE("%d (%s)", ret.error_code(), (ret.message()).c_str()); + callback->SetError(ret); } //Complete task LoggerD("callback: %p error:%d folders.size()=%d", callback, callback->isError(), callback->getFolders().size()); - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - - std::vector response; - auto folders = callback->getFolders(); - std::for_each(folders.begin(), folders.end(), - [&response](std::shared_ptr &folder) { - response.push_back(MessagingUtil::folderToJson(folder)); - } - ); - obj[JSON_DATA] = picojson::value(response); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } else { + LoggerD("Calling success callback"); + + std::vector response; + auto folders = callback->getFolders(); + std::for_each(folders.begin(), folders.end(), + [&response](std::shared_ptr &folder) { + response.push_back(MessagingUtil::folderToJson(folder)); } - } catch (const PlatformException& err) { - LoggerE("Error while calling findFolders callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Unknown error when calling findFolders callback."); + ); + obj[JSON_DATA] = picojson::value(response); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } + } else { + LoggerE("Unknown error when calling findFolders callback."); } delete callback; callback = NULL; } +PlatformResult EmailManager::RemoveConversationsPlatform(ConversationCallbackData* callback) +{ + int error; + std::lock_guard lock(m_mutex); + std::vector> conversations = + callback->getConversations(); + MessageType type = callback->getMessageServiceType(); + + int thread_id = 0; + for(auto it = conversations.begin() ; it != conversations.end(); ++it) { + if ((*it)->getType() != type) { + LoggerE("Invalid message type"); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, + "Error while deleting email conversation"); + } + } + + for (auto it = conversations.begin() ; it != conversations.end(); ++it) { + thread_id = (*it)->getConversationId(); + error = email_delete_thread(thread_id, false); + if (EMAIL_ERROR_NONE != error) { + LoggerE("Couldn't delete email conversation data"); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, + "Error while deleting email conversation"); + } + + // for now, there is no way to recognize deleting email thread job is completed. + // so use polling to wait the thread is removed. + email_mail_data_t *thread_info = NULL; + do { + usleep(300 * 1000); + LoggerD("Waiting to delete this email thread..."); + error = email_get_thread_information_by_thread_id( + thread_id, &thread_info); + + if (thread_info != NULL) { + free(thread_info); + thread_info = NULL; + } + } while (error != EMAIL_ERROR_MAIL_NOT_FOUND); + } + return PlatformResult(ErrorCode::NO_ERROR); +} + void EmailManager::removeConversations(ConversationCallbackData* callback) { LoggerD("Entered"); @@ -1378,81 +1434,28 @@ void EmailManager::removeConversations(ConversationCallbackData* callback) return; } - int error; - try - { - std::lock_guard lock(m_mutex); - std::vector> conversations = - callback->getConversations(); - MessageType type = callback->getMessageServiceType(); - - int thread_id = 0; - for(auto it = conversations.begin() ; it != conversations.end(); ++it) { - if((*it)->getType() != type) { - LoggerE("Invalid message type"); - throw TypeMismatchException("Error while deleting email conversation"); - } - } - - for (auto it = conversations.begin() ; it != conversations.end(); ++it) { - thread_id = (*it)->getConversationId(); - error = email_delete_thread(thread_id, false); - if (EMAIL_ERROR_NONE != error) { - LoggerE("Couldn't delete email conversation data"); - throw UnknownException("Error while deleting email conversation"); - } - - // for now, there is no way to recognize deleting email thread job is completed. - // so use polling to wait the thread is removed. - email_mail_data_t *thread_info = NULL; - do { - usleep(300 * 1000); - LoggerD("Waiting to delete this email thread..."); - error = email_get_thread_information_by_thread_id( - thread_id, &thread_info); - - if (thread_info != NULL) { - free(thread_info); - thread_info = NULL; - } - } while (error != EMAIL_ERROR_MAIL_NOT_FOUND); - } - } - catch (const PlatformException& err) - { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); + PlatformResult ret = RemoveConversationsPlatform(callback); + if (ret.IsError()) { + LoggerE("%d (%s)", ret.error_code(), (ret.message()).c_str()); + callback->SetError(ret); } - catch (...) - { - LoggerE("Email conversation remove failed"); - callback->setError("UnknownError", "Email conversation remove failed"); - } - - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } else { + LoggerD("Calling success callback"); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const PlatformException& err) { - LoggerE("Error while calling removeConversations callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Unknown error when calling removeConversations callback."); + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } + } else { + LoggerE("Unknown error when calling removeConversations callback."); } delete callback; diff --git a/src/messaging/email_manager.h b/src/messaging/email_manager.h index b1623225..efcee6cd 100644 --- a/src/messaging/email_manager.h +++ b/src/messaging/email_manager.h @@ -35,6 +35,7 @@ #include "common/callback_user_data.h" #include "common/platform_exception.h" +#include "common/platform_result.h" #include "messaging_util.h" #include "message_service.h" @@ -58,6 +59,7 @@ class MessageBodyCallbackData; class EmailManager { public: static EmailManager& getInstance(); + static common::PlatformResult InitializeEmailService(); void addDraftMessage(MessageCallbackUserData* callback); void removeMessages(MessagesCallbackUserData* callback); @@ -67,14 +69,14 @@ public: void findFolders(FoldersCallbackData* callback); void removeConversations(ConversationCallbackData* callback); - void sendMessage(MessageRecipientsCallbackData* callback); + common::PlatformResult sendMessage(MessageRecipientsCallbackData* callback); void sendStatusCallback(int mail_id, email_noti_on_network_event status, int error_code); void removeStatusCallback(const std::vector &ids, email_noti_on_storage_event status); void loadMessageBody(MessageBodyCallbackData* callback); - void loadMessageAttachment(MessageAttachmentCallbackData* callback); + common::PlatformResult loadMessageAttachment(MessageAttachmentCallbackData* callback); void sync(void* data); void syncFolder(SyncFolderCallbackData* callback); @@ -95,12 +97,19 @@ private: EmailManager(const EmailManager &); void operator=(const EmailManager &); virtual ~EmailManager(); - void addDraftMessagePlatform(int account_id, + common::PlatformResult addDraftMessagePlatform(int account_id, std::shared_ptr message); - void addOutboxMessagePlatform(int account_id, + common::PlatformResult addOutboxMessagePlatform(int account_id, std::shared_ptr message); - void addMessagePlatform(int account_id, std::shared_ptr message, + common::PlatformResult addMessagePlatform(int account_id, std::shared_ptr message, email_mailbox_type_e mailbox_type); + common::PlatformResult UpdateMessagesPlatform(MessagesCallbackUserData* callback); + common::PlatformResult RemoveMessagesPlatform( + MessagesCallbackUserData* callback); + common::PlatformResult FindMessagesPlatform(FindMsgCallbackUserData* callback); + common::PlatformResult FindConversationsPlatform(ConversationCallbackData* callback); + common::PlatformResult FindFoldersPlatform(FoldersCallbackData* callback); + common::PlatformResult RemoveConversationsPlatform(ConversationCallbackData* callback); typedef std::map SendReqMap; typedef SendReqMap::iterator SendReqMapIterator; @@ -128,6 +137,7 @@ private: DBus::SendProxyPtr m_proxy_send; std::mutex m_mutex; + bool m_is_initialized; }; } // Messaging diff --git a/src/messaging/find_msg_callback_user_data.cc b/src/messaging/find_msg_callback_user_data.cc index 6820ecbd..b23f5bf2 100644 --- a/src/messaging/find_msg_callback_user_data.cc +++ b/src/messaging/find_msg_callback_user_data.cc @@ -88,6 +88,20 @@ void FindMsgCallbackUserData::setError(const std::string& err_name, } } +void FindMsgCallbackUserData::SetError(const common::PlatformResult& error) +{ + // keep only first error in chain + if (!m_is_error) { + m_is_error = true; + picojson::object& obj = m_json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + auto obj_data = picojson::object(); + obj_data[JSON_ERROR_CODE] = picojson::value(static_cast(error.error_code())); + obj_data[JSON_ERROR_MESSAGE] = picojson::value(error.message()); + obj[JSON_DATA] = picojson::value(obj_data); + } +} + bool FindMsgCallbackUserData::isError() const { return m_is_error; diff --git a/src/messaging/find_msg_callback_user_data.h b/src/messaging/find_msg_callback_user_data.h index 29330c43..262aaa57 100644 --- a/src/messaging/find_msg_callback_user_data.h +++ b/src/messaging/find_msg_callback_user_data.h @@ -29,6 +29,7 @@ #include "MsgCommon/AttributeFilter.h" #include "MsgCommon/SortMode.h" #include "messaging_util.h" +#include "common/platform_result.h" using namespace extension::tizen; @@ -51,6 +52,7 @@ public: void setError(const std::string& err_name, const std::string& err_message); + void SetError(const common::PlatformResult& error); bool isError() const; std::string getErrorName() const; std::string getErrorMessage() const; diff --git a/src/messaging/folders_callback_data.cc b/src/messaging/folders_callback_data.cc index 450118ae..fa787ef4 100644 --- a/src/messaging/folders_callback_data.cc +++ b/src/messaging/folders_callback_data.cc @@ -81,6 +81,20 @@ void FoldersCallbackData::setError(const std::string& err_name, } } +void FoldersCallbackData::SetError(const common::PlatformResult& error) +{ + // keep only first error in chain + if (!m_is_error) { + m_is_error = true; + picojson::object& obj = m_json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + auto obj_data = picojson::object(); + obj_data[JSON_ERROR_CODE] = picojson::value(static_cast(error.error_code())); + obj_data[JSON_ERROR_MESSAGE] = picojson::value(error.message()); + obj[JSON_DATA] = picojson::value(obj_data); + } +} + bool FoldersCallbackData::isError() const { return m_is_error; diff --git a/src/messaging/folders_callback_data.h b/src/messaging/folders_callback_data.h index fc1e1393..b453192b 100644 --- a/src/messaging/folders_callback_data.h +++ b/src/messaging/folders_callback_data.h @@ -19,6 +19,7 @@ #define __TIZEN_FOLDERS_CALLBACK_DATA_H__ #include "common/callback_user_data.h" +#include "common/platform_result.h" #include #include @@ -47,6 +48,7 @@ public: void setError(const std::string& err_name, const std::string& err_message); + void SetError(const common::PlatformResult& error); bool isError() const; std::string getErrorName() const; std::string getErrorMessage() const; diff --git a/src/messaging/folders_change_callback.cc b/src/messaging/folders_change_callback.cc index 3fc7b9be..bc526c9e 100644 --- a/src/messaging/folders_change_callback.cc +++ b/src/messaging/folders_change_callback.cc @@ -94,8 +94,12 @@ void FoldersChangeCallback::added(const FolderPtrVector& folders) obj[JSON_ACTION] = picojson::value(FOLDERSADDED); obj[JSON_DATA] = picojson::value(array); - PostQueue::getInstance().addAndResolve(obj.at( - JSON_CALLBACK_ID).get(), PostPriority::MEDIUM, json->serialize()); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + PostQueue::getInstance().addAndResolve(obj.at( + JSON_CALLBACK_ID).get(), PostPriority::MEDIUM, json->serialize()); + } else { + LoggerE("Callback id is missing"); + } } void FoldersChangeCallback::updated(const FolderPtrVector& folders) @@ -121,8 +125,12 @@ void FoldersChangeCallback::updated(const FolderPtrVector& folders) obj[JSON_ACTION] = picojson::value(FOLDERSUPDATED); obj[JSON_DATA] = picojson::value(array); - PostQueue::getInstance().addAndResolve(obj.at( - JSON_CALLBACK_ID).get(), PostPriority::LOW, json->serialize()); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + PostQueue::getInstance().addAndResolve(obj.at( + JSON_CALLBACK_ID).get(), PostPriority::LOW, json->serialize()); + } else { + LoggerE("Callback id is missing"); + } } void FoldersChangeCallback::removed(const FolderPtrVector& folders) @@ -148,8 +156,12 @@ void FoldersChangeCallback::removed(const FolderPtrVector& folders) obj[JSON_ACTION] = picojson::value(FOLDERSREMOVED); obj[JSON_DATA] = picojson::value(array); - PostQueue::getInstance().addAndResolve(obj.at( - JSON_CALLBACK_ID).get(), PostPriority::LAST, json->serialize()); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + PostQueue::getInstance().addAndResolve(obj.at( + JSON_CALLBACK_ID).get(), PostPriority::LAST, json->serialize()); + } else { + LoggerE("Callback id is missing"); + } } void FoldersChangeCallback::setFilter(tizen::AbstractFilterPtr filter) diff --git a/src/messaging/message.cc b/src/messaging/message.cc index 980f4fc2..6406aa6d 100644 --- a/src/messaging/message.cc +++ b/src/messaging/message.cc @@ -10,6 +10,7 @@ #include "common/logger.h" #include "common/platform_exception.h" +#include "common/scope_exit.h" #include "Ecore_File.h" #include "message_email.h" @@ -18,9 +19,14 @@ #include "short_message_manager.h" #include "messaging_util.h" +using common::ErrorCode; +using common::PlatformResult; + namespace extension { namespace messaging { +using namespace common; + // *** constructor Message::Message(): m_id(-1), m_old_id(-1), m_id_set(false), m_conversation_id(-1), @@ -70,6 +76,10 @@ MessageType Message::getType() const return m_type; } +std::string Message::getTypeString() const { + return MessagingUtil::messageTypeToString(getType()); +} + time_t Message::getTimestamp() const { return m_timestamp; @@ -328,7 +338,7 @@ std::string Message::convertEmailRecipients(const std::vector &reci return address; } -std::string saveToTempFile(const std::string &data) +PlatformResult saveToTempFile(const std::string &data, std::string* file_name) { char buf[] = "XXXXXX"; int res = 0; @@ -336,30 +346,31 @@ std::string saveToTempFile(const std::string &data) mode_t mask = umask(S_IWGRP | S_IWOTH); res = mkstemp(buf); //Just generate unique name - std::string fileName = std::string("/tmp/") + buf; + std::string tmp_name = std::string("/tmp/") + buf; mode_t old_mask = umask(mask); - FILE *file = fopen(fileName.c_str(), "w"); + FILE *file = fopen(tmp_name.c_str(), "w"); umask(old_mask); if (NULL == file) { LoggerE("Failed to create file"); - throw common::UnknownException("Failed to create file"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to create file"); } if (fprintf(file, "%s", data.c_str()) < 0) { LoggerE("Failed to write data into file"); - throw common::UnknownException("Failed to write data into file"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to write data into file"); } fflush(file); fclose(file); - return fileName; + *file_name = tmp_name; + return PlatformResult(ErrorCode::NO_ERROR); } -std::string copyFileToTemp(const std::string& sourcePath) +PlatformResult copyFileToTemp(const std::string& sourcePath, std::string* result_path) { LoggerD("Entered"); char buf[] = "XXXXXX"; - std::string dirPath, fileName, attPath, tmpPath; + std::string fileName, attPath, tmpPath; mode_t mask = umask(S_IWGRP | S_IWOTH); int err = mkstemp(buf); @@ -368,7 +379,7 @@ std::string copyFileToTemp(const std::string& sourcePath) } umask(mask); - dirPath = "/tmp/" + std::string(buf); + std::string dirPath = "/tmp/" + std::string(buf); if ( sourcePath[0] != '/' ) { // FIXME When filesystem will be available @@ -381,7 +392,7 @@ std::string copyFileToTemp(const std::string& sourcePath) // Looking for the last occurrence of slash in source path std::size_t slashPos; if ((slashPos = attPath.find_last_of('/')) == std::string::npos) { - throw common::UnknownException( + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while copying file to temp: the source path is invalid."); } @@ -390,7 +401,8 @@ std::string copyFileToTemp(const std::string& sourcePath) LoggerD("attPath: %s, tmpPath: %s", attPath.c_str(), tmpPath.c_str()); if(EINA_TRUE != ecore_file_mkdir(dirPath.c_str())) { - throw common::UnknownException("Unknown error while creating temp directory."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Unknown error while creating temp directory."); } FILE *f1, *f2; @@ -400,13 +412,13 @@ std::string copyFileToTemp(const std::string& sourcePath) f1 = fopen(attPath.c_str(), "rb"); if (!f1) { LoggerE("Fail open attPath"); - return 0; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail open attPath"); } f2 = fopen(tmpPath.c_str(), "wb"); if (!f2) { LoggerE("Fail open tmpPath"); fclose (f1); - return 0; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Fail open tmpPath"); } while ((num = fread(buf, 1, sizeof(buf), f1)) > 0) { @@ -419,28 +431,30 @@ std::string copyFileToTemp(const std::string& sourcePath) if(EINA_TRUE != ret /*ecore_file_cp(attPath.c_str(), tmpPath.c_str())*/) { std::string error = "Unknown error while copying file to temp. "; - throw common::UnknownException(error.c_str()); + return PlatformResult(ErrorCode::UNKNOWN_ERR, error.c_str()); } - return dirPath; + *result_path = dirPath; + return PlatformResult(ErrorCode::NO_ERROR); } -void removeDirFromTemp(const std::string& dirPath) +PlatformResult removeDirFromTemp(const std::string& dirPath) { if(EINA_TRUE != ecore_file_rmdir(dirPath.c_str())) { - throw common::UnknownException("Unknown error while deleting temp directory."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error while deleting temp directory."); } + return PlatformResult(ErrorCode::NO_ERROR); } -email_mail_data_t* Message::convertPlatformEmail(std::shared_ptr message) +PlatformResult Message::convertPlatformEmail(std::shared_ptr message, + email_mail_data_t** result_mail_data) { + email_mail_data_t* mail_data = nullptr; if(EMAIL != message->getType()) { LoggerE("Invalid type"); - throw common::InvalidValuesException("Invalid type."); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid type."); } - email_mail_data_t *mail_data = NULL; - if(message->is_id_set()) { email_get_mail_data(message->getId(), &mail_data); } else { @@ -478,37 +492,41 @@ email_mail_data_t* Message::convertPlatformEmail(std::shared_ptr messag std::shared_ptr body; body = message->getBody(); if(!body->getPlainBody().empty()) { - std::string body_file_path = saveToTempFile(body->getPlainBody()); + std::string body_file_path = ""; + PlatformResult ret = saveToTempFile(body->getPlainBody(), &body_file_path); + if (ret.IsError()) return ret; mail_data->file_path_plain = strdup(body_file_path.c_str()); if(!mail_data->file_path_plain) { LoggerE("Plain Body file is NULL."); free(mail_data); mail_data = NULL; - throw common::UnknownException("Plain Body file is NULL."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Plain Body file is NULL."); } } if(!body->getHtmlBody().empty()) { - std::string html_file_path = saveToTempFile(body->getHtmlBody()); + std::string html_file_path = ""; + PlatformResult ret = saveToTempFile(body->getHtmlBody(), &html_file_path); mail_data->file_path_html = strdup(html_file_path.c_str()); if(!mail_data->file_path_html) { LoggerE("Html Body file is NULL."); free(mail_data); mail_data = NULL; - throw common::UnknownException("Html Body file is NULL."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Html Body file is NULL."); } } else if(!body->getPlainBody().empty()) { // check html data is exist if not exist copy plain body to html body - std::string html_file_path = saveToTempFile(body->getPlainBody()); + std::string html_file_path = ""; + PlatformResult ret = saveToTempFile(body->getPlainBody(), &html_file_path); mail_data->file_path_html = strdup(html_file_path.c_str()); if(!mail_data->file_path_html) { LoggerE("Plain Body file is NULL."); free(mail_data); mail_data = NULL; - throw common::UnknownException("Plain Body file is NULL."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Plain Body file is NULL."); } } } @@ -521,13 +539,16 @@ email_mail_data_t* Message::convertPlatformEmail(std::shared_ptr messag mail_data->priority = EMAIL_MAIL_PRIORITY_NORMAL; } - return mail_data; + *result_mail_data = mail_data; + return PlatformResult(ErrorCode::NO_ERROR); } -void addSingleEmailAttachment(std::shared_ptr message, +PlatformResult addSingleEmailAttachment(std::shared_ptr message, std::shared_ptr att, AttachmentType attType) { - std::string dirPath = copyFileToTemp(att->getFilePath()); + std::string dirPath = ""; + PlatformResult ret = copyFileToTemp(att->getFilePath(), &dirPath); + if (ret.IsError()) return ret; email_attachment_data_t* tmp = new email_attachment_data_t(); tmp->attachment_name = strdup(att->getShortFileName().c_str()); @@ -547,7 +568,7 @@ void addSingleEmailAttachment(std::shared_ptr message, if (EMAIL_ERROR_NONE != err) { LoggerW("Failed to free attachment data"); } - throw common::UnknownException("Unknown error while adding attachment"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Unknown error while adding attachment"); } att->setId(tmp->attachment_id); @@ -557,10 +578,10 @@ void addSingleEmailAttachment(std::shared_ptr message, LoggerW("Failed to free attachment data"); } - removeDirFromTemp(dirPath); + return removeDirFromTemp(dirPath); } -void Message::addEmailAttachments(std::shared_ptr message) +PlatformResult Message::addEmailAttachments(std::shared_ptr message) { LoggerD("Entered"); @@ -569,17 +590,18 @@ void Message::addEmailAttachments(std::shared_ptr message) email_attachment_data_t *attachment_data_list = NULL; email_meeting_request_t *meeting_req = NULL; - AttachmentPtrVector attachments = message->getMessageAttachments(); AttachmentPtrVector inlineAttachments = message->getBody()->getInlineAttachments(); LoggerD("Attachments size: %d", attachments.size()); LoggerD("Inline attachments size: %d", inlineAttachments.size()); LoggerD("Adding attachments for mail id = [%d]\n", message->getId()); for (auto it = attachments.begin(); it != attachments.end(); ++it) { - addSingleEmailAttachment(message, *it, AttachmentType::EXTERNAL); + PlatformResult ret = addSingleEmailAttachment(message, *it, AttachmentType::EXTERNAL); + if (ret.IsError()) return ret; } for (auto it = inlineAttachments.begin(); it != inlineAttachments.end(); ++it) { - addSingleEmailAttachment(message, *it, AttachmentType::INLINE); + PlatformResult ret = addSingleEmailAttachment(message, *it, AttachmentType::INLINE); + if (ret.IsError()) return ret; } //Update of mail on server using function email_update_mail() is not possible. @@ -590,13 +612,16 @@ void Message::addEmailAttachments(std::shared_ptr message) //4. delete mail without attachments //getting mail and attachments data - mail = Message::convertPlatformEmail(message); + PlatformResult ret = Message::convertPlatformEmail(message, &mail); + if (ret.IsError()) return ret; + error = email_get_attachment_data_list(mail->mail_id, &attachment_data_list, &attachment_data_count); if (EMAIL_ERROR_NONE != error) { email_free_mail_data(&mail, 1); email_free_attachment_data(&attachment_data_list,attachment_data_count); LoggerE("Error while adding attachments. Failed to get attachment list."); - throw common::UnknownException("Error while adding attachments. Failed to get attachment list."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Error while adding attachments. Failed to get attachment list."); } //save mail without attachments id @@ -608,7 +633,7 @@ void Message::addEmailAttachments(std::shared_ptr message) email_free_mail_data(&mail, 1); email_free_attachment_data(&attachment_data_list,attachment_data_count); LoggerE("Error while re-adding mail: %d", error); - throw common::UnknownException("Error while re-adding mail"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while re-adding mail"); } LoggerD("mail added - new id = [%d]\n", mail->mail_id); @@ -628,12 +653,13 @@ void Message::addEmailAttachments(std::shared_ptr message) if (EMAIL_ERROR_NONE != error) { email_free_mail_data(&mail, 1); LoggerE("Error while deleting mail from server: %d", error); - throw common::UnknownException("Error while deleting mail from server"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while deleting mail from server"); } email_free_mail_data(&mail, 1); + return PlatformResult(ErrorCode::NO_ERROR); } -void Message::addSMSRecipientsToStruct(const std::vector &recipients, +PlatformResult Message::addSMSRecipientsToStruct(const std::vector &recipients, msg_struct_t &msg) { const unsigned size = recipients.size(); @@ -653,12 +679,13 @@ void Message::addSMSRecipientsToStruct(const std::vector &recipient } else { LoggerE("failed to add address[%d] %s", i, address); - throw common::UnknownException("failed to add address"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "failed to add address"); } } + return PlatformResult(ErrorCode::NO_ERROR); } -void Message::addMMSRecipientsToStruct(const std::vector &recipients, +PlatformResult Message::addMMSRecipientsToStruct(const std::vector &recipients, msg_struct_t &msg, int type) { const unsigned size = recipients.size(); @@ -685,12 +712,13 @@ void Message::addMMSRecipientsToStruct(const std::vector &recipient } else { LoggerE("[%d] failed to add address: [%s], error: %d", i, address, error); - throw common::UnknownException("failed to add address"); + return PlatformResult (ErrorCode::UNKNOWN_ERR, "failed to add address"); } } + return PlatformResult(ErrorCode::NO_ERROR); } -void Message::addMMSBodyAndAttachmentsToStruct(const AttachmentPtrVector attach, +PlatformResult Message::addMMSBodyAndAttachmentsToStruct(const AttachmentPtrVector attach, msg_struct_t &mms_struct, Message* message) { LoggerD("Entered with %d attachments", attach.size()); @@ -755,19 +783,20 @@ void Message::addMMSBodyAndAttachmentsToStruct(const AttachmentPtrVector attach, } } else { LoggerE("att[%d]: failed to add attachment"); - throw common::UnknownException("failed to add attachment"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "failed to add attachment"); } } + return PlatformResult(ErrorCode::NO_ERROR); } -msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, - msg_handle_t handle) +PlatformResult Message::convertPlatformShortMessageToStruct(Message* message, + msg_handle_t handle, msg_struct_t* result_msg) { LoggerD("Entered"); if (message->getType() != SMS && message->getType() != MMS) { LoggerD("Invalid type"); - throw common::InvalidValuesException("Invalid type"); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid type"); } msg_error_t err = MSG_SUCCESS; @@ -781,7 +810,7 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, msg_release_struct(&sendOpt); msg_release_struct(&msg); LoggerD("msg_get_message() Fail [%d]", err); - throw common::UnknownException("msg_get_message() Fail"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "msg_get_message() Fail"); } LoggerD("Using existing msg for id: %d", id); } else { // id is not set - the message does not exist in database @@ -793,7 +822,7 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, msg_release_struct(&sendOpt); msg_release_struct(&msg); LoggerE("Set SMS type error"); - throw common::UnknownException("Set SMS type error"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Set SMS type error"); } } else { // Set message type to MMS @@ -802,7 +831,7 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, msg_release_struct(&sendOpt); msg_release_struct(&msg); LoggerE("Set MMS type error"); - throw common::UnknownException("Set MMS type error"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Set MMS type error"); } } } @@ -825,13 +854,14 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, int error = msg_list_clear(msg, MSG_MESSAGE_ADDR_LIST_HND); if( MSG_SUCCESS != error) { LoggerE("Failed to clear address list, error: %d", error); - throw common::UnknownException("Failed to clear address list"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to clear address list"); } // Set SMS recipients std::vector recp_list = message->getTO(); if (!recp_list.empty()) { - message->addSMSRecipientsToStruct(recp_list, msg); + PlatformResult ret = message->addSMSRecipientsToStruct(recp_list, msg); + if (ret.IsError()) return ret; } } else if (type == MSG_TYPE_MMS) { @@ -839,13 +869,13 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, if (MSG_SUCCESS != msg_set_int_value(msg, MSG_MESSAGE_TYPE_INT, MSG_TYPE_MMS)) { LoggerE("Message(%p): Set MMS type error", message); - throw common::UnknownException("Set MMS type error"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Set MMS type error"); } // Create MMS data msg_struct_t mms_data = msg_create_struct(MSG_STRUCT_MMS); if (mms_data == NULL) { LoggerE("Message(%p): Set MMS data error", message); - throw common::UnknownException("Set MMS data error"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Set MMS data error"); } // Set MMS message subject std::string subject = message->getSubject(); @@ -854,7 +884,7 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, const_cast(subject.c_str()), subject.size()); if (r != MSG_SUCCESS) { LoggerE("Message(%p): Set MMS subject error: %d", message, r); - throw common::UnknownException("Set MMS subject error"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Set MMS subject error"); } } // Set MMS message text @@ -901,14 +931,17 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, msg_set_str_value(media, MSG_MMS_MEDIA_REGION_ID_STR, const_cast("Text"), 4); - std::string body_file_path = saveToTempFile(body->getPlainBody()); + std::string body_file_path = ""; + PlatformResult ret = saveToTempFile(body->getPlainBody(), &body_file_path); + if (ret.IsError()) return ret; + int error = msg_set_str_value(media, MSG_MMS_MEDIA_FILEPATH_STR, const_cast(body_file_path.c_str()), body_file_path.size()); if (error != MSG_SUCCESS) { LoggerE("Message(%p): Failed to set mms body filepath", message); - throw common::UnknownException("Failed to set mms body filepath"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to set mms body filepath"); } msg_set_str_value(media, MSG_MMS_MEDIA_CONTENT_TYPE_STR, "text/plain", 10); @@ -933,13 +966,14 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, msg_set_int_value(mms_data, MSG_MESSAGE_ATTACH_COUNT_INT, attach_list.size()); if (!attach_list.empty()) { - addMMSBodyAndAttachmentsToStruct(attach_list, mms_data, message); + PlatformResult ret =addMMSBodyAndAttachmentsToStruct(attach_list, mms_data, message); + if (ret.IsError()) return ret; } // Set MMS body int r = msg_set_mms_struct(msg, mms_data); if (r != MSG_SUCCESS) { LoggerE("Message(%p): Set MMS body error: %d", message, r); - throw common::UnknownException("Set MMS body error"); + return PlatformResult (ErrorCode::UNKNOWN_ERR, "Set MMS body error"); } msg_release_struct(&mms_data); @@ -947,18 +981,21 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, msg_list_clear(msg, MSG_MESSAGE_ADDR_LIST_HND); std::vector recp_list = message->getTO(); - message->addMMSRecipientsToStruct(recp_list, msg, MSG_RECIPIENTS_TYPE_TO); + PlatformResult ret = message->addMMSRecipientsToStruct(recp_list, msg, MSG_RECIPIENTS_TYPE_TO); + if (ret.IsError()) return ret; recp_list = message->getCC(); - message->addMMSRecipientsToStruct(recp_list, msg, MSG_RECIPIENTS_TYPE_CC); + ret = message->addMMSRecipientsToStruct(recp_list, msg, MSG_RECIPIENTS_TYPE_CC); + if (ret.IsError()) return ret; recp_list = message->getBCC(); - message->addMMSRecipientsToStruct(recp_list, msg, MSG_RECIPIENTS_TYPE_BCC); + ret =message->addMMSRecipientsToStruct(recp_list, msg, MSG_RECIPIENTS_TYPE_BCC); + if (ret.IsError()) return ret; } else { msg_release_struct(&msg); LoggerE("Message(%p): Invalid message type", message); - throw common::InvalidValuesException("Invalid message type"); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid message type"); } // set common attributes for SMS and MMS @@ -992,7 +1029,7 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, msg_set_int_value(msg, MSG_MESSAGE_SIM_INDEX_INT, sim_index+1); if ( MSG_SUCCESS != error) { LoggerE("Failed to set sim index, error: %d", error); - throw common::UnknownException("Failed to set sim index"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to set sim index"); } } @@ -1000,7 +1037,8 @@ msg_struct_t Message::convertPlatformShortMessageToStruct(Message* message, msg_set_bool_value(msg, MSG_MESSAGE_READ_BOOL, message->getIsRead()); LoggerD("End"); - return msg; + *result_msg = msg; + return PlatformResult(ErrorCode::NO_ERROR); } std::string Message::getShortMsgSenderFromStruct(msg_struct_t &msg) @@ -1037,7 +1075,8 @@ std::string Message::getShortMsgSenderFromStruct(msg_struct_t &msg) return std::string(); } -std::vector Message::getSMSRecipientsFromStruct(msg_struct_t &msg) +PlatformResult Message::getSMSRecipientsFromStruct(msg_struct_t &msg, + std::vector* result_address) { std::vector address; msg_list_handle_t addr_list = NULL; @@ -1056,13 +1095,14 @@ std::vector Message::getSMSRecipientsFromStruct(msg_struct_t &msg) } } else { LoggerE("failed to get recipients"); - throw common::UnknownException("failed to add recipients"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "failed to add recipients"); } - return address; + *result_address = address; + return PlatformResult(ErrorCode::NO_ERROR); } -std::vector Message::getMMSRecipientsFromStruct(msg_struct_t &msg, - int type) +PlatformResult Message::getMMSRecipientsFromStruct(msg_struct_t &msg, + int type, std::vector* result_address) { std::vector address; msg_list_handle_t addr_list = NULL; @@ -1086,12 +1126,13 @@ std::vector Message::getMMSRecipientsFromStruct(msg_struct_t &msg, } } else { LoggerE("failed to get recipients"); - throw common::UnknownException("failed to add recipients"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "failed to add recipients"); } - return address; + *result_address = address; + return PlatformResult(ErrorCode::NO_ERROR); } -void Message::setMMSBodyAndAttachmentsFromStruct(Message* message, +PlatformResult Message::setMMSBodyAndAttachmentsFromStruct(Message* message, msg_struct_t &msg) { LoggerD("Entered message(%p)", message); @@ -1103,7 +1144,7 @@ void Message::setMMSBodyAndAttachmentsFromStruct(Message* message, if (MSG_SUCCESS != error) { LoggerE("Cannot get mms struct, error:%d", error); msg_release_struct(&mms_struct); - throw common::UnknownException("cannot get mms struct"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "cannot get mms struct"); } bool body_has_been_set = false; @@ -1152,27 +1193,22 @@ void Message::setMMSBodyAndAttachmentsFromStruct(Message* message, //According to old implementation // "text value on first page goes to body attribute" if ((0 == p) && (MMS_SMIL_MEDIA_TEXT == msg_media_type)) { - LoggerD("Loading body from file: %s ", infoStr); - - try { - message->getBody()->setPlainBody( - MessagingUtil::loadFileContentToString(infoStr)); - body_has_been_set = true; - - LoggerD("Loaded body: %s", - message->getBody()->getPlainBody().c_str()); - - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", - (exception.name()).c_str(), - (exception.message()).c_str()); - LoggerD("[p:%d, m:%d] body is not set", p, m); - } - catch (...) { - LoggerE("Unknown exception occured during plain body loading"); - LoggerD("[p:%d, m:%d] body is not set", p, m); - } - + LoggerD("Loading body from file: %s ", infoStr); + + std::string result = ""; + PlatformResult ret = MessagingUtil::loadFileContentToString(infoStr, &result); + if (ret.IsSuccess()) { + + message->getBody()->setPlainBody(result); + body_has_been_set = true; + + LoggerD("Loaded body: %s", + message->getBody()->getPlainBody().c_str()); + } else { + LoggerE("Unhandled error: %d (%s)!", + ret.error_code(), ret.message().c_str()); + LoggerD("[p:%d, m:%d] body is not set", p, m); + } } else { std::shared_ptr ma (new MessageAttachment()); ma->setFilePath(infoStr); @@ -1201,14 +1237,14 @@ void Message::setMMSBodyAndAttachmentsFromStruct(Message* message, } else { msg_release_struct(&mms_struct); LoggerE("failed to get attachment"); - throw common::UnknownException("failed to get attachment"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "failed to get attachment"); } msg_release_struct(&page); } } else { msg_release_struct(&mms_struct); LoggerE("failed to get attachment"); - throw common::UnknownException("failed to get attachment"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "failed to get attachment"); } if(false == body_has_been_set) { @@ -1266,16 +1302,17 @@ void Message::setMMSBodyAndAttachmentsFromStruct(Message* message, } else { msg_release_struct(&mms_struct); LoggerE("failed to get attachment"); - throw common::UnknownException("failed to add attachment"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "failed to add attachment"); } LoggerD("after MSG_MMS_ATTACH_LIST attachments count is:%d", message->m_attachments.size()); msg_release_struct(&mms_struct); + return PlatformResult(ErrorCode::NO_ERROR); } -Message* Message::convertPlatformShortMessageToObject(msg_struct_t msg){ - Message *message = NULL; +PlatformResult Message::convertPlatformShortMessageToObject(msg_struct_t msg, Message** result_message){ + Message *message = nullptr; int infoInt; bool infoBool; char infoStr[MAX_ADDRESS_VAL_LEN + 1]; @@ -1290,7 +1327,13 @@ Message* Message::convertPlatformShortMessageToObject(msg_struct_t msg){ body->setPlainBody(std::string(msgInfoStr)); message->setBody(body); // get recipients - std::vector recp_list = message->getSMSRecipientsFromStruct(msg); + std::vector recp_list; + PlatformResult ret = message->getSMSRecipientsFromStruct(msg, &recp_list); + if (ret.IsError()) { + if (message) delete message; + return ret; + } + message->setTO(recp_list); } else if (infoInt == MSG_TYPE_MMS) { message = new MessageMMS(); @@ -1331,22 +1374,38 @@ Message* Message::convertPlatformShortMessageToObject(msg_struct_t msg){ } // get recipients - std::vector recp_list = getMMSRecipientsFromStruct(msg, - MSG_RECIPIENTS_TYPE_TO); + std::vector recp_list; + PlatformResult ret = getMMSRecipientsFromStruct(msg, MSG_RECIPIENTS_TYPE_TO, &recp_list); + if (ret.IsError()) { + if (message) delete message; + return ret; + } message->setTO(recp_list); - recp_list = getMMSRecipientsFromStruct(msg, MSG_RECIPIENTS_TYPE_CC); + ret = getMMSRecipientsFromStruct(msg, MSG_RECIPIENTS_TYPE_CC, &recp_list); + if (ret.IsError()) { + if (message) delete message; + return ret; + } message->setCC(recp_list); - recp_list = getMMSRecipientsFromStruct(msg, MSG_RECIPIENTS_TYPE_BCC); + ret = getMMSRecipientsFromStruct(msg, MSG_RECIPIENTS_TYPE_BCC, &recp_list); + if (ret.IsError()) { + if (message) delete message; + return ret; + } message->setBCC(recp_list); // get subject memset(infoStr, 0, MAX_ADDRESS_VAL_LEN + 1); msg_get_str_value(msg, MSG_MESSAGE_SUBJECT_STR, infoStr, MAX_SUBJECT_LEN); message->setSubject(infoStr); //set attachments - setMMSBodyAndAttachmentsFromStruct(message, msg); + ret = setMMSBodyAndAttachmentsFromStruct(message, msg); + if (ret.IsError()) { + if (message) delete message; + return ret; + } } else { LoggerE("Invalid Message type: %d", infoInt); - throw common::InvalidValuesException("Invalid Message type"); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "Invalid Message type"); } // get id @@ -1429,16 +1488,24 @@ Message* Message::convertPlatformShortMessageToObject(msg_struct_t msg){ } LoggerD("End"); - return message; + *result_message = message; + return PlatformResult(ErrorCode::NO_ERROR); } -std::shared_ptr Message::findShortMessageById(const int id) { - - msg_struct_t msg = ShortMsgManager::getInstance().getMessage(id); - std::shared_ptr message( - Message::convertPlatformShortMessageToObject(msg)); - - return message; +PlatformResult Message::findShortMessageById(const int id, MessagePtr* message) { + msg_struct_t msg; + PlatformResult ret = ShortMsgManager::getInstance().getMessage(id, &msg); + if (ret.IsError()) { + return ret; + } + Message* message_ptr = nullptr; + ret = Message::convertPlatformShortMessageToObject(msg, &message_ptr); + msg_release_struct(&msg); + if (ret.IsError()) { + return ret; + } + message->reset(message_ptr); + return PlatformResult(ErrorCode::NO_ERROR); } std::vector Message::split(const std::string& input, @@ -1484,42 +1551,48 @@ std::shared_ptr Message::convertEmailToMessageBody( return body; } -AttachmentPtrVector Message::convertEmailToMessageAttachment(email_mail_data_t& mail) +PlatformResult Message::convertEmailToMessageAttachment(email_mail_data_t& mail, + AttachmentPtrVector* att) { - LoggerD("Enter"); - email_attachment_data_t* attachment = NULL; - int attachmentCount = 0; - - AttachmentPtrVector att; + LoggerD("Enter"); + email_attachment_data_t* attachment = NULL; + int attachmentCount = 0; - if (EMAIL_ERROR_NONE != email_get_attachment_data_list(mail.mail_id, - &attachment, &attachmentCount)) { - throw common::UnknownException("Couldn't get attachment."); - } - if ( attachment && attachmentCount > 0) { - for (int i = 0; i < attachmentCount; i++) { - std::shared_ptr tmp_att (new MessageAttachment()); - tmp_att->updateWithAttachmentData(attachment[i]); - att.push_back(tmp_att); - } + if (EMAIL_ERROR_NONE != email_get_attachment_data_list(mail.mail_id, + &attachment, &attachmentCount)) { + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Couldn't get attachment."); + } + if ( attachment && attachmentCount > 0) { + for (int i = 0; i < attachmentCount; i++) { + std::shared_ptr tmp_att (new MessageAttachment()); + tmp_att->updateWithAttachmentData(attachment[i]); + att->push_back(tmp_att); } + } - email_free_attachment_data(&attachment, attachmentCount); - return att; + email_free_attachment_data(&attachment, attachmentCount); + return PlatformResult(ErrorCode::NO_ERROR); } -std::shared_ptr Message::convertPlatformEmailToObject( - email_mail_data_t& mail) +PlatformResult Message::convertPlatformEmailToObject( + email_mail_data_t& mail, std::shared_ptr* result) { LoggerD("Enter"); - std::shared_ptr message(new MessageEmail()); - message->updateEmailMessage(mail); - return message; + Message* message = new MessageEmail(); + PlatformResult ret = message->updateEmailMessage(mail); + if (ret.IsError()) { + delete message; + return ret; + } + (*result).reset(message); + return PlatformResult(ErrorCode::NO_ERROR); } -void Message::updateEmailMessage(email_mail_data_t& mail) +PlatformResult Message::updateEmailMessage(email_mail_data_t& mail) { LoggerW("This should be called on MessageEmail instance"); + return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, + "This should be called on MessageEmail instance"); } /** @@ -1591,8 +1664,7 @@ bool Message::isMatchingAttribute(const std::string& attribute_name, match_flag); } else if (TYPE == attribute_name) { - const std::string msgTypeStr = MessagingUtil::messageTypeToString(getType()); - return FilterUtils::isStringMatching(key, msgTypeStr, match_flag); + return FilterUtils::isStringMatching(key, getTypeString(), match_flag); } else if (FROM == attribute_name) { return FilterUtils::isStringMatching(key, getFrom() , match_flag); diff --git a/src/messaging/message.h b/src/messaging/message.h index 0c66d1a1..00274a69 100644 --- a/src/messaging/message.h +++ b/src/messaging/message.h @@ -20,6 +20,7 @@ #include "messaging_util.h" #include "message_body.h" #include "MsgCommon/AbstractFilter.h" +#include "common/platform_result.h" namespace extension { namespace messaging { @@ -51,6 +52,7 @@ public: int getConversationId() const; int getFolderId() const; MessageType getType() const; + std::string getTypeString() const; time_t getTimestamp() const; std::string getFrom() const; std::vector getTO() const; @@ -106,44 +108,48 @@ public: // service id bool is_service_is_set() const; // gets recipients list for SMS message - void addSMSRecipientsToStruct(const std::vector &recipients, + common::PlatformResult addSMSRecipientsToStruct(const std::vector &recipients, msg_struct_t &msg); // gets recipients list for SMS message - void addMMSRecipientsToStruct(const std::vector &recipients, + common::PlatformResult addMMSRecipientsToStruct(const std::vector &recipients, msg_struct_t &msg, int type); /** * Updates message with data from email_mail_data_t structure. * @param mail */ - virtual void updateEmailMessage(email_mail_data_t& mail); + virtual common::PlatformResult updateEmailMessage(email_mail_data_t& mail); // gets from(sender) address from short msg struct static std::string getShortMsgSenderFromStruct(msg_struct_t &msg); // function for filling msg_struct_t fields - static msg_struct_t convertPlatformShortMessageToStruct(Message* message, - msg_handle_t handle); + static common::PlatformResult convertPlatformShortMessageToStruct(Message* message, + msg_handle_t handle, msg_struct_t* result); // gets recipients list for SMS message - std::vector getSMSRecipientsFromStruct(msg_struct_t &msg); + common::PlatformResult getSMSRecipientsFromStruct(msg_struct_t &msg, + std::vector* result_address); // gets recipients list for MMS message - static std::vector getMMSRecipientsFromStruct(msg_struct_t &msg, - int type); + static common::PlatformResult getMMSRecipientsFromStruct(msg_struct_t &msg, + int type, std::vector* result_address); // function for filling Message attributes - static Message* convertPlatformShortMessageToObject(msg_struct_t msg); - static std::shared_ptr findShortMessageById(const int id); - static void addMMSBodyAndAttachmentsToStruct(const AttachmentPtrVector attach, + static common::PlatformResult convertPlatformShortMessageToObject(msg_struct_t msg, Message** message); + static common::PlatformResult findShortMessageById(const int id, MessagePtr* message); + static common::PlatformResult addMMSBodyAndAttachmentsToStruct(const AttachmentPtrVector attach, msg_struct_t &mms_struct, Message* message); - static void setMMSBodyAndAttachmentsFromStruct(Message *message, + static common::PlatformResult setMMSBodyAndAttachmentsFromStruct(Message *message, msg_struct_t &msg); - static email_mail_data_t* convertPlatformEmail(std::shared_ptr message); - static void addEmailAttachments(std::shared_ptr message); + static common::PlatformResult convertPlatformEmail(std::shared_ptr message, + email_mail_data_t** result); + static common::PlatformResult addEmailAttachments(std::shared_ptr message); static std::string convertEmailRecipients(const std::vector &recipients); static std::vector getEmailRecipientsFromStruct(const char *recipients); - static std::shared_ptr convertPlatformEmailToObject(email_mail_data_t& mail); + static common::PlatformResult convertPlatformEmailToObject(email_mail_data_t& mail, + std::shared_ptr* result); static std::shared_ptr convertEmailToMessageBody(email_mail_data_t& mail); - static AttachmentPtrVector convertEmailToMessageAttachment(email_mail_data_t& mail); + static common::PlatformResult convertEmailToMessageAttachment(email_mail_data_t& mail, + AttachmentPtrVector* result); // tizen::FilterableObject virtual bool isMatchingAttribute(const std::string& attribute_name, diff --git a/src/messaging/message_body.cc b/src/messaging/message_body.cc index 90ae6679..36ad740e 100644 --- a/src/messaging/message_body.cc +++ b/src/messaging/message_body.cc @@ -12,6 +12,8 @@ namespace extension { namespace messaging { +using namespace common; + MessageBody::MessageBody() : m_messageId(1), m_messageId_set(false), m_loaded(false), @@ -92,31 +94,37 @@ bool MessageBody::is_message_id_set() const return m_messageId_set; } -void MessageBody::updateBody(email_mail_data_t& mail) +PlatformResult MessageBody::updateBody(email_mail_data_t& mail) { LoggerD("Enter"); setMessageId(mail.mail_id); setLoaded(mail.body_download_status); if (mail.file_path_plain) { - try { - LoggerD("Plain body"); - setPlainBody(MessagingUtil::loadFileContentToString(mail.file_path_plain)); - } catch (...) { - LoggerE("Fail to open plain body."); - throw common::UnknownException("Fail to open plain body."); - } + LoggerD("Plain body"); + std::string result = ""; + PlatformResult ret = MessagingUtil::loadFileContentToString(mail.file_path_plain, + &result); + if (ret.IsError()) { + LoggerE("Fail to open plain body."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Fail to open plain body."); + } + setPlainBody(result); } if (mail.file_path_html) { - try { - LoggerD("Html body"); - setHtmlBody(MessagingUtil::loadFileContentToString(mail.file_path_html)); - } catch (...) { - LoggerE("Fail to open html body."); - throw common::UnknownException("Fail to open html body."); - } + std::string result = ""; + PlatformResult ret = MessagingUtil::loadFileContentToString(mail.file_path_html, + &result); + if (ret.IsError()) { + LoggerE("Fail to open html body."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Fail to open html body."); + } + setHtmlBody(result); } + return PlatformResult(ErrorCode::NO_ERROR); } } // messaging diff --git a/src/messaging/message_body.h b/src/messaging/message_body.h index 6b0073ad..fb48f9e8 100644 --- a/src/messaging/message_body.h +++ b/src/messaging/message_body.h @@ -10,6 +10,7 @@ #include #include "message_attachment.h" +#include "common/platform_result.h" namespace extension { namespace messaging { @@ -41,7 +42,7 @@ public: * Updates body with data from email_mail_data_t structure. * @param mail */ - void updateBody(email_mail_data_t& mail); + common::PlatformResult updateBody(email_mail_data_t& mail); private: int m_messageId; diff --git a/src/messaging/message_callback_user_data.cc b/src/messaging/message_callback_user_data.cc index d95f4f09..4fab0554 100644 --- a/src/messaging/message_callback_user_data.cc +++ b/src/messaging/message_callback_user_data.cc @@ -54,6 +54,22 @@ void MessageCallbackUserData::setError(const std::string& err_name, } } +void MessageCallbackUserData::setError(const common::PlatformResult& error) +{ + // keep only first error in chain + if (!m_is_error) { + m_is_error = true; + picojson::object& obj = m_json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + auto obj_data = picojson::object(); + + obj_data[JSON_ERROR_CODE] = picojson::value(static_cast(error.error_code())); + obj_data[JSON_ERROR_MESSAGE] = picojson::value(error.message()); + + obj[JSON_DATA] = picojson::value(obj_data); + } +} + bool MessageCallbackUserData::isError() const { return m_is_error; diff --git a/src/messaging/message_callback_user_data.h b/src/messaging/message_callback_user_data.h index b96eed0b..a3447098 100644 --- a/src/messaging/message_callback_user_data.h +++ b/src/messaging/message_callback_user_data.h @@ -6,6 +6,7 @@ #define MESSAGING_MESSAGE_CALLBACK_USER_DATA_H_ #include "common/callback_user_data.h" +#include "common/platform_result.h" #include #include @@ -28,6 +29,7 @@ public: void setError(const std::string& err_name, const std::string& err_message); + void setError(const common::PlatformResult& error); bool isError() const; std::string getErrorName() const; std::string getErrorMessage() const; diff --git a/src/messaging/message_conversation.cc b/src/messaging/message_conversation.cc index 316c6e0d..5dcecbf8 100644 --- a/src/messaging/message_conversation.cc +++ b/src/messaging/message_conversation.cc @@ -11,6 +11,9 @@ #define MAX_THREAD_DATA_LEN 128 +using common::ErrorCode; +using common::PlatformResult; + namespace extension { namespace messaging { @@ -42,6 +45,10 @@ MessageType MessageConversation::getType() const return m_conversation_type; } +std::string MessageConversation::getTypeString() const { + return MessagingUtil::messageTypeToString(getType()); +} + time_t MessageConversation::getTimestamp() const { return m_timestamp; @@ -97,8 +104,8 @@ int MessageConversation::getLastMessageId() const return m_last_message_id; } -std::shared_ptr MessageConversation::convertMsgConversationToObject( - unsigned int threadId, msg_handle_t handle) +PlatformResult MessageConversation::convertMsgConversationToObject( + unsigned int threadId, msg_handle_t handle, std::shared_ptr* result) { std::shared_ptr conversation (new MessageConversation()); @@ -119,146 +126,140 @@ std::shared_ptr MessageConversation::convertMsgConversation unsigned int lastMsgIndex = 0; char msgData[MAX_THREAD_DATA_LEN] = {0,}; - try { - msgInfo = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); - sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT); + msgInfo = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); + std::unique_ptr::type, int(*)(msg_struct_t*)> + msg_info_ptr(&msgInfo, &msg_release_struct); + // automatically release the memory + sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT); + std::unique_ptr::type, int(*)(msg_struct_t*)> + send_opt_ptr(&sendOpt, &msg_release_struct); + // automatically release the memory + + conversation->m_conversation_id = threadId; + + msg_thread = msg_create_struct(MSG_STRUCT_THREAD_INFO); + std::unique_ptr::type, int(*)(msg_struct_t*)> + msg_thread_ptr(&msg_thread, &msg_release_struct); + // automatically release the memory + err = msg_get_thread(handle, conversation->m_conversation_id, msg_thread); + if (err != MSG_SUCCESS) + { + LoggerE("Failed to retrieve thread."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to retrieve thread."); + } + msg_get_int_value(msg_thread, MSG_THREAD_MSG_TYPE_INT, &tempInt); + switch(tempInt) + { + case MSG_TYPE_SMS: + case MSG_TYPE_SMS_CB: + case MSG_TYPE_SMS_JAVACB: + case MSG_TYPE_SMS_WAPPUSH: + case MSG_TYPE_SMS_MWI: + case MSG_TYPE_SMS_SYNCML: + case MSG_TYPE_SMS_REJECT: + conversation->m_conversation_type = SMS; + break; + case MSG_TYPE_MMS: + case MSG_TYPE_MMS_JAVA: + case MSG_TYPE_MMS_NOTI: + conversation->m_conversation_type = MMS; + break; + } - conversation->m_conversation_id = threadId; + msg_get_int_value(msg_thread, MSG_THREAD_MSG_TIME_INT, &tempInt); + conversation->m_timestamp = tempInt; - msg_thread = msg_create_struct(MSG_STRUCT_THREAD_INFO); - err = msg_get_thread(handle, conversation->m_conversation_id, msg_thread); - if (err != MSG_SUCCESS) - { - LoggerE("Failed to retrieve thread."); - throw common::UnknownException("Failed to retrieve thread."); - } - msg_get_int_value(msg_thread, MSG_THREAD_MSG_TYPE_INT, &tempInt); - switch(tempInt) - { - case MSG_TYPE_SMS: - case MSG_TYPE_SMS_CB: - case MSG_TYPE_SMS_JAVACB: - case MSG_TYPE_SMS_WAPPUSH: - case MSG_TYPE_SMS_MWI: - case MSG_TYPE_SMS_SYNCML: - case MSG_TYPE_SMS_REJECT: - conversation->m_conversation_type = SMS; - break; - case MSG_TYPE_MMS: - case MSG_TYPE_MMS_JAVA: - case MSG_TYPE_MMS_NOTI: - conversation->m_conversation_type = MMS; - break; - } + msg_get_int_value(msg_thread, MSG_THREAD_UNREAD_COUNT_INT, &tempInt); + conversation->m_unread_messages = tempInt; - msg_get_int_value(msg_thread, MSG_THREAD_MSG_TIME_INT, &tempInt); - conversation->m_timestamp = tempInt; + msg_get_str_value(msg_thread, MSG_THREAD_MSG_DATA_STR, msgData, MAX_THREAD_DATA_LEN); - msg_get_int_value(msg_thread, MSG_THREAD_UNREAD_COUNT_INT, &tempInt); - conversation->m_unread_messages = tempInt; + conversation->m_preview = msgData; - msg_get_str_value(msg_thread, MSG_THREAD_MSG_DATA_STR, msgData, MAX_THREAD_DATA_LEN); - - conversation->m_preview = msgData; + err = msg_get_conversation_view_list(handle, conversation->m_conversation_id, + &convViewList); + std::unique_ptr::type, int(*)(msg_struct_list_s*)> + conv_view_list_ptr(&convViewList, &msg_release_list_struct); + // automatically release the memory + if (err != MSG_SUCCESS) + { + LoggerE("Get conversation(msg) view list fail."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Get conversation(msg) view list fail."); + } - err = msg_get_conversation_view_list(handle, conversation->m_conversation_id, - &convViewList); - if (err != MSG_SUCCESS) - { - LoggerE("Get conversation(msg) view list fail."); - throw common::UnknownException("Get conversation(msg) view list fail."); - } + lastMsgIndex = convViewList.nCount - 1; + conversation->m_count = convViewList.nCount; - lastMsgIndex = convViewList.nCount - 1; - conversation->m_count = convViewList.nCount; + msg_get_bool_value(convViewList.msg_struct_info[lastMsgIndex], MSG_CONV_MSG_READ_BOOL, &tempBool); + conversation->m_is_read = tempBool; - msg_get_bool_value(convViewList.msg_struct_info[lastMsgIndex], MSG_CONV_MSG_READ_BOOL, &tempBool); - conversation->m_is_read = tempBool; + msg_get_int_value(convViewList.msg_struct_info[lastMsgIndex], MSG_CONV_MSG_ID_INT, &tempInt); + conversation->m_last_message_id = tempInt; - msg_get_int_value(convViewList.msg_struct_info[lastMsgIndex], MSG_CONV_MSG_ID_INT, &tempInt); - conversation->m_last_message_id = tempInt; + if (msg_get_message(handle, conversation->m_last_message_id, msgInfo, + sendOpt) != MSG_SUCCESS) + { + LoggerE("Get message fail."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "get message fail."); + } - if (msg_get_message(handle, conversation->m_last_message_id, msgInfo, - sendOpt) != MSG_SUCCESS) - { - LoggerE("Get message fail."); - throw common::UnknownException("get message fail."); - } + msg_get_int_value(convViewList.msg_struct_info[lastMsgIndex], MSG_CONV_MSG_DIRECTION_INT, &tempInt); - msg_get_int_value(convViewList.msg_struct_info[lastMsgIndex], MSG_CONV_MSG_DIRECTION_INT, &tempInt); + msg_get_list_handle(msgInfo, MSG_MESSAGE_ADDR_LIST_HND, (void **)&addr_list); + nToCnt = msg_list_length(addr_list); - msg_get_list_handle(msgInfo, MSG_MESSAGE_ADDR_LIST_HND, (void **)&addr_list); - nToCnt = msg_list_length(addr_list); + if (MSG_DIRECTION_TYPE_MT == tempInt) + { + if (nToCnt > 0 && nToCnt < MAX_TO_ADDRESS_CNT ) + { + char strNumber[MAX_ADDRESS_VAL_LEN] = {0,}; + addr_info = (msg_struct_t)msg_list_nth_data(addr_list, nToCnt-1); + msg_get_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, strNumber, MAX_ADDRESS_VAL_LEN); - if (MSG_DIRECTION_TYPE_MT == tempInt) + if (strNumber[0] != '\0') { - if (nToCnt > 0 && nToCnt < MAX_TO_ADDRESS_CNT ) - { - char strNumber[MAX_ADDRESS_VAL_LEN] = {0,}; - addr_info = (msg_struct_t)msg_list_nth_data(addr_list, nToCnt-1); - msg_get_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, strNumber, MAX_ADDRESS_VAL_LEN); - - if (strNumber[0] != '\0') - { - conversation->m_from = strNumber; - } - else - { - LoggerD("address is null "); - } - } - else - { - LoggerD("address count index fail"); - } + conversation->m_from = strNumber; } else { - if (nToCnt > 0 && nToCnt < MAX_TO_ADDRESS_CNT ) - { - for (int index = 0; index < nToCnt; index++) - { - addr_info = (msg_struct_t)msg_list_nth_data(addr_list, index); - char strNumber[MAX_ADDRESS_VAL_LEN] = {0,}; - msg_get_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, strNumber, MAX_ADDRESS_VAL_LEN); - - conversation->m_to.push_back(strNumber); - } - } - else - { - LoggerD("address fetch fail"); - } + LoggerD("address is null "); } + } + else + { + LoggerD("address count index fail"); + } + } + else + { + if (nToCnt > 0 && nToCnt < MAX_TO_ADDRESS_CNT ) + { + for (int index = 0; index < nToCnt; index++) + { + addr_info = (msg_struct_t)msg_list_nth_data(addr_list, index); + char strNumber[MAX_ADDRESS_VAL_LEN] = {0,}; + msg_get_str_value(addr_info, MSG_ADDRESS_INFO_ADDRESS_VALUE_STR, strNumber, MAX_ADDRESS_VAL_LEN); - char strTemp[MAX_SUBJECT_LEN] = {0}; - msg_get_str_value(msgInfo, MSG_MESSAGE_SUBJECT_STR, strTemp, MAX_SUBJECT_LEN); - - conversation->m_conversation_subject = strTemp; - msg_release_list_struct(&convViewList); - msg_release_struct(&msgInfo); - msg_release_struct(&sendOpt); - msg_release_struct(&msg_thread); - } catch (const common::PlatformException& ex) { - msg_release_list_struct(&convViewList); - msg_release_struct(&msgInfo); - msg_release_struct(&sendOpt); - msg_release_struct(&msg_thread); - LoggerE("%s (%s)", (ex.name()).c_str(), (ex.message()).c_str()); - throw common::UnknownException("Unable to convert short message conversation."); - } catch (...) { - msg_release_list_struct(&convViewList); - msg_release_struct(&msgInfo); - msg_release_struct(&sendOpt); - msg_release_struct(&msg_thread); - throw common::UnknownException("Unable to convert short message conversation."); + conversation->m_to.push_back(strNumber); + } + } + else + { + LoggerD("address fetch fail"); + } } - return conversation; + char strTemp[MAX_SUBJECT_LEN] = {0}; + msg_get_str_value(msgInfo, MSG_MESSAGE_SUBJECT_STR, strTemp, MAX_SUBJECT_LEN); + + conversation->m_conversation_subject = strTemp; + + *result = conversation; + return PlatformResult(ErrorCode::NO_ERROR); } -std::shared_ptr MessageConversation::convertEmailConversationToObject( - unsigned int threadId) +PlatformResult MessageConversation::convertEmailConversationToObject( + unsigned int threadId, std::shared_ptr* result) { std::shared_ptr conversation (new MessageConversation()); @@ -267,12 +268,12 @@ std::shared_ptr MessageConversation::convertEmailConversati if(email_get_thread_information_ex(threadId, &resultMail) != EMAIL_ERROR_NONE) { LoggerE("Couldn't get conversation"); - throw common::UnknownException("Couldn't get conversation."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Couldn't get conversation."); } else { if (!resultMail) { LoggerE("Data is null"); - throw common::UnknownException("Get email data fail."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Get email data fail."); } email_mail_data_t* mailData = NULL; @@ -281,12 +282,12 @@ std::shared_ptr MessageConversation::convertEmailConversati &mailData) != EMAIL_ERROR_NONE) { free(resultMail); - throw common::UnknownException("Get email data fail."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Get email data fail."); } if (!mailData) { free(resultMail); - throw common::UnknownException("Get email data fail."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Get email data fail."); } int index = 0; @@ -300,7 +301,7 @@ std::shared_ptr MessageConversation::convertEmailConversati { email_free_mail_data(&mailData , 1); free(resultMail); - throw common::UnknownException("Get email data list fail."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Get email data list fail."); } for (index = 0; index < count; index++) @@ -367,26 +368,8 @@ std::shared_ptr MessageConversation::convertEmailConversati free(resultMail); } - return conversation; -} - -std::shared_ptr MessageConversation::convertConversationStructToObject( - unsigned int threadId, MessageType msgType, msg_handle_t handle) -{ - std::shared_ptr conversation (new MessageConversation()); - - if (MessageType::EMAIL == msgType) { - conversation = convertEmailConversationToObject(threadId); - } else { - if(handle != NULL) { - conversation = convertMsgConversationToObject(threadId, handle); - } else { - LoggerE("Handle has not been sent."); - throw common::UnknownException("Handle has not been sent."); - } - } - - return conversation; + *result = conversation; + return PlatformResult(ErrorCode::NO_ERROR); } void MessageConversation::setConversationId(int id) @@ -501,9 +484,7 @@ bool MessageConversation::isMatchingAttribute(const std::string& attribute_name, match_flag); } else if(TYPE == attribute_name) { - const MessageType msg_type = getType(); - const std::string msg_type_str = MessagingUtil::messageTypeToString(msg_type); - return FilterUtils::isStringMatching(key, msg_type_str, match_flag); + return FilterUtils::isStringMatching(key, getTypeString(), match_flag); } else if(MESSAGE_COUNT == attribute_name) { return FilterUtils::isStringMatching(key, std::to_string(getMessageCount()), diff --git a/src/messaging/message_conversation.h b/src/messaging/message_conversation.h index 489eb12a..dfb8b467 100644 --- a/src/messaging/message_conversation.h +++ b/src/messaging/message_conversation.h @@ -37,6 +37,7 @@ public: // attributes getters int getConversationId() const; MessageType getType() const; + std::string getTypeString() const; time_t getTimestamp() const; unsigned long getMessageCount() const; unsigned long getUnreadMessages() const; @@ -49,18 +50,16 @@ public: std::vector getBCC() const; int getLastMessageId() const; - static std::shared_ptr convertConversationStructToObject( - unsigned int threadId, MessageType msgType, msg_handle_t handle = NULL); - static std::shared_ptr convertEmailConversationToObject( - unsigned int threadId); + static common::PlatformResult convertEmailConversationToObject( + unsigned int threadId, std::shared_ptr* result); /** * * @param threadId Id of Message (not Conversation) * @param handle * @return */ - static std::shared_ptr convertMsgConversationToObject( - unsigned int threadId, msg_handle_t handle); + static common::PlatformResult convertMsgConversationToObject( + unsigned int threadId, msg_handle_t handle, std::shared_ptr* result); virtual void setConversationId(int id); virtual void setType(MessageType type); diff --git a/src/messaging/message_email.cc b/src/messaging/message_email.cc index a2cf0f13..f5c56515 100644 --- a/src/messaging/message_email.cc +++ b/src/messaging/message_email.cc @@ -9,6 +9,8 @@ namespace extension { namespace messaging { +using namespace common; + MessageEmail::MessageEmail(): Message() { @@ -76,7 +78,7 @@ bool MessageEmail::getHasAttachment() const return m_has_attachment || !m_body->getInlineAttachments().empty(); } -void MessageEmail::updateEmailMessage(email_mail_data_t& mail) +PlatformResult MessageEmail::updateEmailMessage(email_mail_data_t& mail) { LoggerD("Enter"); @@ -114,7 +116,8 @@ void MessageEmail::updateEmailMessage(email_mail_data_t& mail) setSubject(mail.subject); } - getBody()->updateBody(mail); + PlatformResult ret = getBody()->updateBody(mail); + if (ret.IsError()) return ret; if (mail.mail_id != mail.thread_id) { setInResponseTo(mail.thread_id); @@ -139,9 +142,12 @@ void MessageEmail::updateEmailMessage(email_mail_data_t& mail) break; } - AttachmentPtrVector att = convertEmailToMessageAttachment(mail); + AttachmentPtrVector att; + ret = convertEmailToMessageAttachment(mail, &att); + if (ret.IsError()) return ret; setMessageAttachments(att); + return PlatformResult(ErrorCode::NO_ERROR); } } // messaging diff --git a/src/messaging/message_email.h b/src/messaging/message_email.h index f91d614b..a2514061 100644 --- a/src/messaging/message_email.h +++ b/src/messaging/message_email.h @@ -29,7 +29,7 @@ public: * Updates message with data from email_mail_data_t structure. * @param mail */ - virtual void updateEmailMessage(email_mail_data_t& mail); + virtual common::PlatformResult updateEmailMessage(email_mail_data_t& mail); private: // function that verifies recipient's list validity diff --git a/src/messaging/message_service.cc b/src/messaging/message_service.cc index c79809d7..17211124 100644 --- a/src/messaging/message_service.cc +++ b/src/messaging/message_service.cc @@ -14,6 +14,9 @@ #include "message_storage_short_msg.h" #include "message.h" +using common::ErrorCode; +using common::PlatformResult; + namespace extension { namespace messaging { @@ -28,6 +31,7 @@ const char* JSON_SERVICE_STORAGE = "messageStorage"; MessageRecipientsCallbackData::MessageRecipientsCallbackData(): m_is_error(false), + m_account_id(-1), m_sim_index(TAPI_NETWORK_DEFAULT_DATA_SUBS_UNKNOWN), m_default_sim_index(TAPI_NETWORK_DEFAULT_DATA_SUBS_UNKNOWN) { @@ -66,41 +70,34 @@ void MessageRecipientsCallbackData::setError(const std::string& err_name, { // keep only first error in chain if (!m_is_error) { + m_is_error = true; picojson::object& obj = m_json->get(); obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); - auto objData = picojson::object(); + auto obj_error = picojson::object(); - objData[JSON_ERROR_NAME] = picojson::value(err_name); - objData[JSON_ERROR_MESSAGE] = picojson::value(err_message); + obj_error[JSON_ERROR_NAME] = picojson::value(err_name); + obj_error[JSON_ERROR_MESSAGE] = picojson::value(err_message); - obj[JSON_DATA] = picojson::value(objData); + obj[JSON_DATA] = picojson::value(obj_error); + } +} - m_is_error = true; - m_err_name = err_name; - m_err_message = err_message; - if (m_message) { - m_err_message += " for: "; - // platform issue: we cannot get error per recipient - // so all recipients are added to error message - std::vector recp_list = m_message->getTO(); - unsigned int count = recp_list.size(); - for (unsigned int i = 0; i < count; ++i) { - m_err_message += recp_list.at(i) + ", "; - } - recp_list = m_message->getCC(); - count = recp_list.size(); - for (unsigned int i = 0; i < count; ++i) { - m_err_message += recp_list.at(i) + ", "; - } - recp_list = m_message->getBCC(); - count = recp_list.size(); - for (unsigned int i = 0; i < count; ++i) { - m_err_message += recp_list.at(i) + ", "; - } +void MessageRecipientsCallbackData::setError(const PlatformResult& error) +{ + // keep only first error in chain + if (!m_is_error) { + m_is_error = true; - } - } + picojson::object& obj = m_json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + auto obj_error = picojson::object(); + + obj_error[JSON_ERROR_CODE] = picojson::value(static_cast(error.error_code())); + obj_error[JSON_ERROR_MESSAGE] = picojson::value(error.message()); + + obj[JSON_DATA] = picojson::value(obj_error); + } } bool MessageRecipientsCallbackData::isError() const @@ -170,7 +167,8 @@ TelNetworkDefaultDataSubs_t MessageRecipientsCallbackData::getDefaultSimIndex() BaseMessageServiceCallbackData::BaseMessageServiceCallbackData(): // CallbackUserData(globalCtx), m_is_error(false), - m_op_handle(-1) + m_op_handle(-1), + m_callback_id(-1) { LoggerD("Entered"); } @@ -186,8 +184,6 @@ void BaseMessageServiceCallbackData::setError(const std::string& err_name, // keep only first error in chain if (!m_is_error) { m_is_error = true; - m_err_name = err_name; - m_err_message = err_message; picojson::object& obj = m_json->get(); obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); @@ -199,19 +195,26 @@ void BaseMessageServiceCallbackData::setError(const std::string& err_name, } } -bool BaseMessageServiceCallbackData::isError() const +void BaseMessageServiceCallbackData::setError(const PlatformResult& error) { - return m_is_error; -} + // keep only first error in chain + if (!m_is_error) { + m_is_error = true; -std::string BaseMessageServiceCallbackData::getErrorName() const -{ - return m_err_name; + picojson::object& obj = m_json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + auto obj_error = picojson::object(); + + obj_error[JSON_ERROR_CODE] = picojson::value(static_cast(error.error_code())); + obj_error[JSON_ERROR_MESSAGE] = picojson::value(error.message()); + + obj[JSON_DATA] = picojson::value(obj_error); + } } -std::string BaseMessageServiceCallbackData::getErrorMessage() const +bool BaseMessageServiceCallbackData::isError() const { - return m_err_message; + return m_is_error; } void BaseMessageServiceCallbackData::setOperationHandle(const int op_handle) @@ -297,6 +300,7 @@ SyncCallbackData::SyncCallbackData(): // BaseMessageServiceCallbackData(globalCtx), m_is_limit(false), m_limit(0), + m_op_id(-1), m_account_id(-1) { LoggerD("Entered"); @@ -370,7 +374,7 @@ std::shared_ptr SyncFolderCallbackData::getMessageFolder() const MessageService::MessageService(int id, MessageType msgType, - std::string name): + const std::string& name): m_id(id), m_msg_type(msgType), m_name(name) @@ -385,8 +389,9 @@ MessageService::MessageService(int id, m_storage.reset(new MessageStorageEmail(id)); break; default: - LoggerE("Undefined message type"); - throw common::InvalidValuesException("Undefined message type"); + LoggerE("Undefined message type: %d", msgType); + assert(false); + break; } } @@ -399,7 +404,7 @@ picojson::object MessageService::toPicoJS() const { picojson::object picojs = picojson::object(); picojs[JSON_SERVICE_ID] = picojson::value(std::to_string(m_id)); - picojs[JSON_SERVICE_TYPE] = picojson::value(MessagingUtil::messageTypeToString(m_msg_type)); + picojs[JSON_SERVICE_TYPE] = picojson::value(getMsgServiceTypeString()); picojs[JSON_SERVICE_NAME] = picojson::value(m_name); return picojs; } @@ -419,6 +424,10 @@ MessageType MessageService::getMsgServiceType() const return m_msg_type; } +std::string MessageService::getMsgServiceTypeString() const { + return MessagingUtil::messageTypeToString(getMsgServiceType()); +} + std::string MessageService::getMsgServiceName() const { return m_name; @@ -429,50 +438,55 @@ MessageStoragePtr MessageService::getMsgStorage() const return m_storage; } -void MessageService::sendMessage(MessageRecipientsCallbackData *callback) +common::PlatformResult MessageService::sendMessage(MessageRecipientsCallbackData *callback) { // this method should be overwritten be specific services LoggerE("Cannot send message"); - throw common::NotSupportedException("Cannot send message"); + delete callback; + return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Unable to send message."); } -void MessageService::loadMessageBody(MessageBodyCallbackData* callback) +PlatformResult MessageService::loadMessageBody(MessageBodyCallbackData* callback) { // this method should be overwritten by specific services LoggerE("Cannot load message body"); - throw common::NotSupportedException("Cannot load message body"); + delete callback; + return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Cannot load message body"); } -void MessageService::loadMessageAttachment(MessageAttachmentCallbackData* callback) +PlatformResult MessageService::loadMessageAttachment(MessageAttachmentCallbackData* callback) { // this method should be overwritten by email service // for MMS and SMS this function is not supported LoggerE("Cannot load message attachment"); - throw common::NotSupportedException("Cannot load message attachment"); + delete callback; + return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Cannot load message attachment"); } -long MessageService::sync(SyncCallbackData *callback) +PlatformResult MessageService::sync(SyncCallbackData *callback, long* operation_id) { // this method should be overwritten by email service // for MMS and SMS this function is not supported LoggerE("Cannot sync with external server"); - throw common::NotSupportedException("Cannot sync with external server"); + delete callback; + return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Cannot sync with external server"); } -long MessageService::syncFolder(SyncFolderCallbackData *callback) +PlatformResult MessageService::syncFolder(SyncFolderCallbackData *callback, long* operation_id) { // this method should be overwritten by email service // for MMS and SMS this function is not supported LoggerE("Cannot sync folder with external server"); - throw common::NotSupportedException("Cannot sync folder with external server"); + delete callback; + return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Cannot sync folder with external server"); } -void MessageService::stopSync(long op_id) +PlatformResult MessageService::stopSync(long op_id) { // this method should be overwritten by email service // for MMS and SMS this function is not supported LoggerE("Cannot stop sync with external server"); - throw common::NotSupportedException("Cannot stop sync with external server"); + return PlatformResult(ErrorCode::NOT_SUPPORTED_ERR, "Cannot stop sync with external server"); } } // messaging diff --git a/src/messaging/message_service.h b/src/messaging/message_service.h index 6e09b1dd..c0dfe361 100755 --- a/src/messaging/message_service.h +++ b/src/messaging/message_service.h @@ -12,6 +12,7 @@ #include "common/picojson.h" #include "common/callback_user_data.h" +#include "common/platform_result.h" #include "messaging_util.h" #include "message_storage.h" @@ -40,6 +41,7 @@ public: void setError(const std::string& err_name, const std::string& err_message); + void setError(const common::PlatformResult& error); bool isError() const; void setAccountId(int account_id); @@ -54,8 +56,6 @@ public: private: std::shared_ptr m_message; bool m_is_error; - std::string m_err_name; - std::string m_err_message; std::vector m_msg_recipients; int m_account_id; TelNetworkDefaultDataSubs_t m_sim_index; @@ -69,9 +69,8 @@ public: void setError(const std::string& err_name, const std::string& err_message); + void setError(const common::PlatformResult& error); bool isError() const; - std::string getErrorName() const; - std::string getErrorMessage() const; /** * This handle is returned from various native API functions: @@ -88,8 +87,6 @@ public: protected: bool m_is_error; - std::string m_err_name; - std::string m_err_message; int m_op_handle; double m_callback_id; @@ -172,16 +169,17 @@ public: virtual int getMsgServiceId() const; virtual std::string getMsgServiceIdStr() const; virtual MessageType getMsgServiceType() const; + std::string getMsgServiceTypeString() const; virtual std::string getMsgServiceName() const; virtual MessageStoragePtr getMsgStorage() const; - virtual void sendMessage(MessageRecipientsCallbackData *callback); - virtual void loadMessageBody(MessageBodyCallbackData* callback); - virtual void loadMessageAttachment(MessageAttachmentCallbackData* callback); - virtual long sync(SyncCallbackData *callback); - virtual long syncFolder(SyncFolderCallbackData *callback); - virtual void stopSync(long op_id); + virtual common::PlatformResult sendMessage(MessageRecipientsCallbackData *callback); + virtual common::PlatformResult loadMessageBody(MessageBodyCallbackData* callback); + virtual common::PlatformResult loadMessageAttachment(MessageAttachmentCallbackData* callback); + virtual common::PlatformResult sync(SyncCallbackData *callback, long* operation_id); + virtual common::PlatformResult syncFolder(SyncFolderCallbackData *callback, long* operation_id); + virtual common::PlatformResult stopSync(long op_id); picojson::object toPicoJS() const; @@ -192,7 +190,7 @@ protected: */ MessageService(int id, MessageType msgType, - std::string name); + const std::string& name); int m_id; MessageType m_msg_type; diff --git a/src/messaging/message_service_email.cc b/src/messaging/message_service_email.cc index e13a568e..0ae93aa1 100644 --- a/src/messaging/message_service_email.cc +++ b/src/messaging/message_service_email.cc @@ -7,6 +7,9 @@ #include "common/logger.h" +using common::ErrorCode; +using common::PlatformResult; + namespace extension { namespace messaging { @@ -25,35 +28,24 @@ MessageServiceEmail::~MessageServiceEmail() static gboolean sendMessageTask(void* data) { - LoggerD("Entered"); + LoggerD("Entered"); - try { - EmailManager::getInstance().sendMessage( - static_cast(data)); + auto ret = EmailManager::getInstance().sendMessage(static_cast(data)); - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", (exception.name()).c_str(), - (exception.message()).c_str()); - } catch(...) { - LoggerE("Unhandled exception!"); - } + if (!ret) { + LoggerE("Error: %d - %s", ret.error_code(), ret.message().c_str()); + } - return FALSE; + return FALSE; } -void MessageServiceEmail::sendMessage(MessageRecipientsCallbackData *callback) +PlatformResult MessageServiceEmail::sendMessage(MessageRecipientsCallbackData *callback) { LoggerD("Entered"); if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } - - if (m_msg_type != callback->getMessage()->getType()) { - - LoggerE("Incorrect message type"); - throw common::TypeMismatchException("Incorrect message type"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Callback is null"); } callback->setAccountId(m_id); @@ -62,215 +54,192 @@ void MessageServiceEmail::sendMessage(MessageRecipientsCallbackData *callback) if (!id) { LoggerE("g_idle_add fails"); delete callback; - throw common::UnknownException("Could not add task"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not add task"); } + + return PlatformResult(ErrorCode::NO_ERROR); } static gboolean loadMessageBodyTask(void* data) { LoggerD("Entered"); - try { - EmailManager::getInstance().loadMessageBody(static_cast(data)); - - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", (exception.name()).c_str(), - (exception.message()).c_str()); - } catch(...) { - LoggerE("Unhandled exception!"); - } + + EmailManager::getInstance().loadMessageBody(static_cast(data)); return FALSE; } -void MessageServiceEmail::loadMessageBody(MessageBodyCallbackData* callback) +PlatformResult MessageServiceEmail::loadMessageBody(MessageBodyCallbackData* callback) { LoggerD("Entered"); if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Callback is null"); } guint id = g_idle_add(loadMessageBodyTask, static_cast(callback)); if (!id) { LoggerE("g_idle_add failed"); delete callback; - throw common::UnknownException("Could not add task"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not add task"); } + + return PlatformResult(ErrorCode::NO_ERROR); } static gboolean loadMessageAttachmentTask(void* data) { - LoggerD("Entered"); - - try { - MessageAttachmentCallbackData *callback = - static_cast(data); - if (!callback) { - LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } - - std::shared_ptr att = callback->getMessageAttachment(); - - // if the attachment is already saved, then it doesn't need to load again. - if (att->isFilePathSet() && att->isSaved()){ - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - picojson::object args; - args[JSON_DATA_MESSAGE_ATTACHMENT] = MessagingUtil::messageAttachmentToJson( - callback->getMessageAttachment()); - obj[JSON_DATA] = picojson::value(args); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - - delete callback; - callback = NULL; - return FALSE; - } - - EmailManager::getInstance().loadMessageAttachment( - static_cast(data)); - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", (exception.name()).c_str(), - (exception.message()).c_str()); - } catch(...) { - LoggerE("Unhandled exception!"); - } - return FALSE; + LoggerD("Entered"); + + auto callback = static_cast(data); + + if (callback) { + auto att = callback->getMessageAttachment(); + + // if the attachment is already saved, then it doesn't need to load again. + if (att->isFilePathSet() && att->isSaved()) { + auto json = callback->getJson(); + picojson::object& obj = json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + picojson::object args; + args[JSON_DATA_MESSAGE_ATTACHMENT] = MessagingUtil::messageAttachmentToJson(att); + obj[JSON_DATA] = picojson::value(args); + + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); + } else { + LoggerE("json is incorrect - missing required member"); + } + delete callback; + callback = nullptr; + } else { + const auto ret = EmailManager::getInstance().loadMessageAttachment(callback); + + if (!ret) { + LoggerE("Error: %d - %s", ret.error_code(), ret.message().c_str()); + } + } + } else { + LoggerE("Callback is null"); + } + + return FALSE; } -void MessageServiceEmail::loadMessageAttachment(MessageAttachmentCallbackData *callback) +PlatformResult MessageServiceEmail::loadMessageAttachment(MessageAttachmentCallbackData *callback) { - LoggerD("Entered"); - guint id = g_idle_add(loadMessageAttachmentTask, static_cast(callback)); - if (!id) { - LoggerE("g_idle_add failed"); - delete callback; - throw common::UnknownException("Could not add task"); - } + LoggerD("Entered"); + guint id = g_idle_add(loadMessageAttachmentTask, static_cast(callback)); + if (!id) { + LoggerE("g_idle_add failed"); + delete callback; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not add task"); + } + return PlatformResult(ErrorCode::NO_ERROR); } static gboolean syncTask(void* data) { - LoggerD("Entered"); - - try { - EmailManager::getInstance().sync(data); + LoggerD("Entered"); - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", (exception.name()).c_str(), - (exception.message()).c_str()); - } catch(...) { - LoggerE("Unhandled exception!"); - } + EmailManager::getInstance().sync(data); - return FALSE; + return FALSE; } -long MessageServiceEmail::sync(SyncCallbackData *callback) +PlatformResult MessageServiceEmail::sync(SyncCallbackData *callback, long* operation_id) { - LoggerD("Entered"); - if (!callback) { - LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } - - long op_id = EmailManager::getInstance().getUniqueOpId(); - callback->setOpId(op_id); - - guint id = g_idle_add(syncTask, static_cast(callback)); - if (!id) { - LoggerE("g_idle_add failed"); - delete callback; - throw common::UnknownException("Could not add task"); - } - return op_id; + LoggerD("Entered"); + + if (!callback) { + LoggerE("Callback is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Callback is null"); + } + + long op_id = EmailManager::getInstance().getUniqueOpId(); + callback->setOpId(op_id); + + guint id = g_idle_add(syncTask, static_cast(callback)); + if (!id) { + LoggerE("g_idle_add failed"); + delete callback; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not add task"); + } + *operation_id = op_id; + return PlatformResult(ErrorCode::NO_ERROR); } static gboolean syncFolderTask(void* data) { LoggerD("Entered"); - try { - EmailManager::getInstance().syncFolder( - static_cast(data)); - - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", (exception.name()).c_str(), - (exception.message()).c_str()); - } catch(...) { - LoggerE("Unhandled exception!"); - } + EmailManager::getInstance().syncFolder(static_cast(data)); return FALSE; } -long MessageServiceEmail::syncFolder(SyncFolderCallbackData *callback) +PlatformResult MessageServiceEmail::syncFolder(SyncFolderCallbackData *callback, long* operation_id) { - LoggerD("Entered"); - if(!callback){ - LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } - - if(!callback->getMessageFolder()) { - LoggerE("Message folder is null"); - throw common::TypeMismatchException("Message folder is null"); - } - - long op_id = EmailManager::getInstance().getUniqueOpId(); - callback->setOpId(op_id); - - guint id = g_idle_add(syncFolderTask, callback); - if (!id) { - LoggerE("g_idle_add fails"); - delete callback; - } - - return op_id; + LoggerD("Entered"); + if (!callback) { + LoggerE("Callback is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Callback is null"); + } + + if (!callback->getMessageFolder()) { + LoggerE("Message folder is null"); + delete callback; + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Message folder is null"); + } + + long op_id = EmailManager::getInstance().getUniqueOpId(); + callback->setOpId(op_id); + + guint id = g_idle_add(syncFolderTask, callback); + if (!id) { + LoggerE("g_idle_add fails"); + delete callback; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not add task"); + } + *operation_id = op_id; + return PlatformResult(ErrorCode::NO_ERROR); } static gboolean stopSyncTask(void* data) { - LoggerD("Entered"); - - try { - if (!data) { - LoggerE("opId is null"); - return FALSE; - } - - const long op_id = *(static_cast(data)); - delete static_cast(data); - data = NULL; - EmailManager::getInstance().stopSync(op_id); - - } catch(const common::PlatformException& exception) { - LoggerE("Unhandled exception: %s (%s)!", (exception.name()).c_str(), - (exception.message()).c_str()); - } catch(...) { - LoggerE("Unhandled exception!"); - } + LoggerD("Entered"); + if (!data) { + LoggerE("opId is null"); return FALSE; + } + + const long op_id = *(static_cast(data)); + delete static_cast(data); + data = NULL; + EmailManager::getInstance().stopSync(op_id); + + return FALSE; } -void MessageServiceEmail::stopSync(long op_id) +PlatformResult MessageServiceEmail::stopSync(long op_id) { - LoggerD("Entered"); - long* data = new long(op_id); - guint id = g_idle_add(stopSyncTask, static_cast(data)); - if (!id) { - LoggerE("g_idle_add failed"); - delete data; - data = NULL; - throw common::UnknownException("Could not add task"); - } + LoggerD("Entered"); + + long* data = new long(op_id); + guint id = g_idle_add(stopSyncTask, static_cast(data)); + + if (!id) { + LoggerE("g_idle_add failed"); + delete data; + data = NULL; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not add task"); + } + return PlatformResult(ErrorCode::NO_ERROR); } } // messaging diff --git a/src/messaging/message_service_email.h b/src/messaging/message_service_email.h index 6ee8858a..844ac4fc 100755 --- a/src/messaging/message_service_email.h +++ b/src/messaging/message_service_email.h @@ -16,12 +16,12 @@ public: MessageServiceEmail(int id, std::string name); virtual ~MessageServiceEmail(); - virtual void sendMessage(MessageRecipientsCallbackData *callback); - virtual void loadMessageBody(MessageBodyCallbackData* callback); - virtual void loadMessageAttachment(MessageAttachmentCallbackData* callback); - virtual long sync(SyncCallbackData *callback); - virtual long syncFolder(SyncFolderCallbackData *callback); - virtual void stopSync(long op_id); + virtual common::PlatformResult sendMessage(MessageRecipientsCallbackData *callback); + virtual common::PlatformResult loadMessageBody(MessageBodyCallbackData* callback); + virtual common::PlatformResult loadMessageAttachment(MessageAttachmentCallbackData* callback); + virtual common::PlatformResult sync(SyncCallbackData *callback, long* operation_id); + virtual common::PlatformResult syncFolder(SyncFolderCallbackData *callback, long* operation_id); + virtual common::PlatformResult stopSync(long op_id); }; } // messaging diff --git a/src/messaging/message_service_short_msg.cc b/src/messaging/message_service_short_msg.cc index 32cc2783..d45e6690 100644 --- a/src/messaging/message_service_short_msg.cc +++ b/src/messaging/message_service_short_msg.cc @@ -20,6 +20,9 @@ //using namespace DeviceAPI::Common; +using common::ErrorCode; +using common::PlatformResult; + namespace extension { namespace messaging { @@ -38,29 +41,22 @@ MessageServiceShortMsg::~MessageServiceShortMsg() static gboolean sendMessageThread(void* data) { - LoggerD("Entered"); + LoggerD("Entered"); - auto callback = static_cast(data); - if (!callback) { - LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } + auto ret = ShortMsgManager::getInstance().sendMessage(static_cast(data)); - // TODO - ShortMsgManager::getInstance().sendMessage(callback); - return FALSE; + if (!ret) { + LoggerE("Error: %d - %s", ret.error_code(), ret.message().c_str()); + } + + return FALSE; } -void MessageServiceShortMsg::sendMessage(MessageRecipientsCallbackData *callback) +PlatformResult MessageServiceShortMsg::sendMessage(MessageRecipientsCallbackData *callback) { if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } - - if (m_msg_type != callback->getMessage()->getType()) { - LoggerE("Incorrect message type"); - throw common::TypeMismatchException("Incorrect message type"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Callback is null"); } /* @@ -100,7 +96,8 @@ void MessageServiceShortMsg::sendMessage(MessageRecipientsCallbackData *callback if (sim_index >= sim_count) { LoggerE("Sim index out of count %d : %d", sim_index, sim_count); - throw common::InvalidValuesException("The index of sim is out of bound"); + delete callback; + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, "The index of sim is out of bound"); } callback->getMessage()->setSimIndex(sim_index); @@ -110,8 +107,11 @@ void MessageServiceShortMsg::sendMessage(MessageRecipientsCallbackData *callback if(!g_idle_add(sendMessageThread, static_cast(callback))) { LoggerE("g_idle_add fails"); - throw common::UnknownException("Could not add task"); + delete callback; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not add task"); } + + return PlatformResult(ErrorCode::NO_ERROR); } static gboolean loadMessageBodyTask(void* data) @@ -123,50 +123,51 @@ static gboolean loadMessageBodyTask(void* data) return FALSE; } - try { - std::shared_ptr body = callback->getMessage()->getBody(); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - picojson::object args; - args[JSON_DATA_MESSAGE_BODY] = MessagingUtil::messageBodyToJson(body); - obj[JSON_DATA] = picojson::value(args); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } catch (...) { - LoggerE("Couldn't create JSMessage object!"); - common::UnknownException e("Loade message body failed"); - callback->setError(e.name(), e.message()); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } + std::shared_ptr body = callback->getMessage()->getBody(); + auto json = callback->getJson(); + picojson::object& obj = json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + picojson::object args; + args[JSON_DATA_MESSAGE_BODY] = MessagingUtil::messageBodyToJson(body); + obj[JSON_DATA] = picojson::value(args); + + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); + } else { + LoggerE("json is incorrect - missing required member"); + } return FALSE; } -void MessageServiceShortMsg::loadMessageBody(MessageBodyCallbackData *callback) +PlatformResult MessageServiceShortMsg::loadMessageBody(MessageBodyCallbackData *callback) { if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } - - if (m_msg_type != callback->getMessage()->getType()) { - LoggerE("Incorrect message type"); - throw common::TypeMismatchException("Incorrect message type"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Callback is null"); } guint id = g_idle_add(loadMessageBodyTask, static_cast(callback)); if (!id) { LoggerE("g_idle_add fails"); - throw common::UnknownException("Could not add task"); + delete callback; + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Could not add task"); } + + return PlatformResult(ErrorCode::NO_ERROR); +} + +MessageServiceShortMsg* MessageServiceShortMsg::GetMmsMessageService() { + return new (std::nothrow) MessageServiceShortMsg( + MessageServiceAccountId::MMS_ACCOUNT_ID, MessageType::MMS); +} + +MessageServiceShortMsg* MessageServiceShortMsg::GetSmsMessageService() { + return new (std::nothrow) MessageServiceShortMsg( + MessageServiceAccountId::SMS_ACCOUNT_ID, MessageType::SMS); } } // namespace messaging diff --git a/src/messaging/message_service_short_msg.h b/src/messaging/message_service_short_msg.h index 27489935..b7d53f02 100644 --- a/src/messaging/message_service_short_msg.h +++ b/src/messaging/message_service_short_msg.h @@ -13,12 +13,17 @@ namespace messaging { class MessageServiceShortMsg : public MessageService { public: - MessageServiceShortMsg(int id, MessageType msgType); virtual ~MessageServiceShortMsg(); - void sendMessage(MessageRecipientsCallbackData *callback); + common::PlatformResult sendMessage(MessageRecipientsCallbackData *callback); + + virtual common::PlatformResult loadMessageBody(MessageBodyCallbackData *callback); - virtual void loadMessageBody(MessageBodyCallbackData *callback); + static MessageServiceShortMsg* GetMmsMessageService(); + static MessageServiceShortMsg* GetSmsMessageService(); + +protected: + MessageServiceShortMsg(int id, MessageType msgType); }; } // namespace messaging diff --git a/src/messaging/message_storage.cc b/src/messaging/message_storage.cc index d5abfe54..935bac24 100644 --- a/src/messaging/message_storage.cc +++ b/src/messaging/message_storage.cc @@ -36,6 +36,10 @@ MessageType MessageStorage::getMsgServiceType() const return m_msg_type; } +std::string MessageStorage::getMsgServiceTypeString() const { + return MessagingUtil::messageTypeToString(getMsgServiceType()); +} + long MessageStorage::addMessagesChangeListener(std::shared_ptr callback) { LoggerD("Entered"); diff --git a/src/messaging/message_storage.h b/src/messaging/message_storage.h index d6573708..7b7b89c3 100644 --- a/src/messaging/message_storage.h +++ b/src/messaging/message_storage.h @@ -7,6 +7,7 @@ #include +#include "common/platform_result.h" #include "common/logger.h" #include "messaging_util.h" @@ -33,6 +34,7 @@ public: virtual int getMsgServiceId() const; virtual MessageType getMsgServiceType() const; + std::string getMsgServiceTypeString() const; virtual void addDraftMessage(MessageCallbackUserData* callback) = 0; virtual void removeMessages(MessagesCallbackUserData* callback) = 0; diff --git a/src/messaging/message_storage_email.cc b/src/messaging/message_storage_email.cc index 6668e511..3cc6e62c 100644 --- a/src/messaging/message_storage_email.cc +++ b/src/messaging/message_storage_email.cc @@ -44,11 +44,14 @@ static gboolean callError(void* data) return FALSE; } - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - + auto json = callback->getJson(); + picojson::object& obj = json->get(); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + PostQueue::getInstance().resolve(obj.at(JSON_CALLBACK_ID).get(), + json->serialize()); + } else { + LoggerE("json is incorrect - missing required member"); + } return FALSE; } @@ -57,19 +60,7 @@ void MessageStorageEmail::addDraftMessage(MessageCallbackUserData* callback) { if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } - - if (m_msg_type != callback->getMessage()->getType()) { - LoggerE("Incorrect message type"); - callback->setError("UnknownError", "Incorrect message type"); - guint id = g_idle_add(callError, static_cast(callback)); - if (!id) { - LoggerE("g_idle_add failed"); - delete callback; - callback = NULL; - } - return; + return; } callback->setAccountId(m_id); @@ -98,7 +89,7 @@ void MessageStorageEmail::removeMessages(MessagesCallbackUserData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setMessageServiceType(m_msg_type); @@ -127,7 +118,7 @@ void MessageStorageEmail::updateMessages(MessagesCallbackUserData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setMessageServiceType(m_msg_type); @@ -155,7 +146,7 @@ void MessageStorageEmail::findMessages(FindMsgCallbackUserData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setAccountId(m_id); @@ -185,7 +176,7 @@ void MessageStorageEmail::findConversations(ConversationCallbackData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setAccountId(m_id); @@ -214,7 +205,7 @@ void MessageStorageEmail::removeConversations(ConversationCallbackData* callback if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setMessageServiceType(m_msg_type); @@ -243,7 +234,7 @@ void MessageStorageEmail::findFolders(FoldersCallbackData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } guint id = g_idle_add(findFoldersTask, static_cast(callback)); diff --git a/src/messaging/message_storage_short_msg.cc b/src/messaging/message_storage_short_msg.cc index 87755a20..1a5fdd57 100644 --- a/src/messaging/message_storage_short_msg.cc +++ b/src/messaging/message_storage_short_msg.cc @@ -37,18 +37,14 @@ void MessageStorageShortMsg::addDraftMessage(MessageCallbackUserData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); - } - - if (m_msg_type != callback->getMessage()->getType()) { - LoggerE("Incorrect message type"); - throw common::TypeMismatchException("Incorrect message type"); + return; } guint id = g_idle_add(addDraftMessageTask, static_cast(callback)); if (!id) { LoggerE("g_idle_add failed"); - throw common::UnknownException("g_idle_add failed"); + delete callback; + return; } } @@ -67,7 +63,7 @@ void MessageStorageShortMsg::removeMessages(MessagesCallbackUserData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setMessageServiceType(m_msg_type); @@ -75,7 +71,8 @@ void MessageStorageShortMsg::removeMessages(MessagesCallbackUserData* callback) guint id = g_idle_add(removeMessagesTask, static_cast(callback)); if (!id) { LoggerE("g_idle_add failed"); - throw common::UnknownException("g_idle_add failed"); + delete callback; + return; } } @@ -94,7 +91,7 @@ void MessageStorageShortMsg::updateMessages(MessagesCallbackUserData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setMessageServiceType(m_msg_type); @@ -102,7 +99,8 @@ void MessageStorageShortMsg::updateMessages(MessagesCallbackUserData* callback) guint id = g_idle_add(updateMessagesTask, static_cast(callback)); if (!id) { LoggerE("g_idle_add failed"); - throw common::UnknownException("g_idle_add failed"); + delete callback; + return; } } @@ -121,7 +119,7 @@ void MessageStorageShortMsg::findMessages(FindMsgCallbackUserData* callback) if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setMessageServiceType(m_msg_type); @@ -129,7 +127,8 @@ void MessageStorageShortMsg::findMessages(FindMsgCallbackUserData* callback) guint id = g_idle_add(findMessagesTask, static_cast(callback)); if (!id) { LoggerE("g_idle_add failed"); - throw common::UnknownException("g_idle_add failed"); + delete callback; + return; } } @@ -148,7 +147,7 @@ void MessageStorageShortMsg::findConversations(ConversationCallbackData* callbac if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setMessageServiceType(m_msg_type); @@ -156,7 +155,8 @@ void MessageStorageShortMsg::findConversations(ConversationCallbackData* callbac guint id = g_idle_add(findConversationsTask, static_cast(callback)); if (!id) { LoggerE("g_idle_add failed"); - throw common::UnknownException("g_idle_add failed"); + delete callback; + return; } } @@ -175,7 +175,7 @@ void MessageStorageShortMsg::removeConversations(ConversationCallbackData* callb if (!callback) { LoggerE("Callback is null"); - throw common::UnknownException("Callback is null"); + return; } callback->setMessageServiceType(m_msg_type); @@ -183,7 +183,8 @@ void MessageStorageShortMsg::removeConversations(ConversationCallbackData* callb guint id = g_idle_add(removeConversationsTask, static_cast(callback)); if (!id) { LoggerE("g_idle_add failed"); - throw common::UnknownException("g_idle_add failed"); + delete callback; + return; } } @@ -196,22 +197,26 @@ static gboolean findFoldersCB(void* data) auto json = callback->getJson(); picojson::object& obj = json->get(); - picojson::array array; - auto each = [&array](std::shared_ptr folder)->void { + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + picojson::array array; + auto each = [&array](std::shared_ptr folder)->void { array.push_back(MessagingUtil::folderToJson(folder)); - }; + }; - auto folders = callback->getFolders(); - for_each(folders.begin(), folders.end(), each); + auto folders = callback->getFolders(); + for_each(folders.begin(), folders.end(), each); - obj[JSON_DATA] = picojson::value(array); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + obj[JSON_DATA] = picojson::value(array); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); + } else { + LoggerE("json is incorrect - missing required member"); + } delete callback; callback = NULL; @@ -227,7 +232,7 @@ void MessageStorageShortMsg::findFolders(FoldersCallbackData* callback) return; } - std::string content_type = MessagingUtil::messageTypeToString(m_msg_type); + std::string content_type = getMsgServiceTypeString(); std::string empty = ""; std::shared_ptr folder; diff --git a/src/messaging/messages_callback_user_data.cc b/src/messaging/messages_callback_user_data.cc index a541c766..257bb54b 100644 --- a/src/messaging/messages_callback_user_data.cc +++ b/src/messaging/messages_callback_user_data.cc @@ -59,6 +59,20 @@ void MessagesCallbackUserData::setError(const std::string& err_name, } } +void MessagesCallbackUserData::SetError(const common::PlatformResult& error) +{ + // keep only first error in chain + if (!m_is_error) { + m_is_error = true; + picojson::object& obj = m_json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + auto obj_data = picojson::object(); + obj_data[JSON_ERROR_CODE] = picojson::value(static_cast(error.error_code())); + obj_data[JSON_ERROR_MESSAGE] = picojson::value(error.message()); + obj[JSON_DATA] = picojson::value(obj_data); + } +} + bool MessagesCallbackUserData::isError() const { return m_is_error; diff --git a/src/messaging/messages_callback_user_data.h b/src/messaging/messages_callback_user_data.h index b39806f0..7317c84c 100644 --- a/src/messaging/messages_callback_user_data.h +++ b/src/messaging/messages_callback_user_data.h @@ -6,6 +6,7 @@ #define MESSAGING_MESSAGES_CALLBACK_USER_DATA_H_ #include "common/callback_user_data.h" +#include "common/platform_result.h" #include #include @@ -28,6 +29,7 @@ public: void setError(const std::string& err_name, const std::string& err_message); + void SetError(const common::PlatformResult& error); bool isError() const; std::string getErrorName() const; std::string getErrorMessage() const; diff --git a/src/messaging/messages_change_callback.cc b/src/messaging/messages_change_callback.cc index b7c2dda1..3806c3ad 100644 --- a/src/messaging/messages_change_callback.cc +++ b/src/messaging/messages_change_callback.cc @@ -123,11 +123,15 @@ void MessagesChangeCallback::added(const MessagePtrVector& msgs) auto json = m_callback_data.getJson(); picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(MESSAGESADDED); - obj[JSON_DATA] = picojson::value(array); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + obj[JSON_ACTION] = picojson::value(MESSAGESADDED); + obj[JSON_DATA] = picojson::value(array); - PostQueue::getInstance().addAndResolve(obj.at( - JSON_CALLBACK_ID).get(), PostPriority::MEDIUM, json->serialize()); + PostQueue::getInstance().addAndResolve(obj.at( + JSON_CALLBACK_ID).get(), PostPriority::MEDIUM, json->serialize()); + } else { + LoggerE("json is incorrect - missing required member"); + } } void MessagesChangeCallback::updated(const MessagePtrVector& msgs) @@ -156,11 +160,15 @@ void MessagesChangeCallback::updated(const MessagePtrVector& msgs) auto json = m_callback_data.getJson(); picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(MESSAGESUPDATED); - obj[JSON_DATA] = picojson::value(array); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + obj[JSON_ACTION] = picojson::value(MESSAGESUPDATED); + obj[JSON_DATA] = picojson::value(array); - PostQueue::getInstance().addAndResolve(obj.at( - JSON_CALLBACK_ID).get(), PostPriority::LOW, json->serialize()); + PostQueue::getInstance().addAndResolve(obj.at( + JSON_CALLBACK_ID).get(), PostPriority::LOW, json->serialize()); + } else { + LoggerE("json is incorrect - missing required member"); + } } void MessagesChangeCallback::removed(const MessagePtrVector& msgs) @@ -190,12 +198,16 @@ void MessagesChangeCallback::removed(const MessagePtrVector& msgs) auto json = m_callback_data.getJson(); picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(MESSAGESREMOVED); - LoggerD("MESSAGES: %s", picojson::value(array).serialize().c_str()); - obj[JSON_DATA] = picojson::value(array); + if (json->contains(JSON_CALLBACK_ID) && obj.at(JSON_CALLBACK_ID).is()) { + obj[JSON_ACTION] = picojson::value(MESSAGESREMOVED); + LoggerD("MESSAGES: %s", picojson::value(array).serialize().c_str()); + obj[JSON_DATA] = picojson::value(array); - PostQueue::getInstance().addAndResolve(obj.at( - JSON_CALLBACK_ID).get(), PostPriority::LAST, json->serialize()); + PostQueue::getInstance().addAndResolve(obj.at( + JSON_CALLBACK_ID).get(), PostPriority::LAST, json->serialize()); + } else { + LoggerE("json is incorrect - missing required member"); + } } void MessagesChangeCallback::setFilter(tizen::AbstractFilterPtr filter) diff --git a/src/messaging/messaging_api.js b/src/messaging/messaging_api.js index fb0d7718..0cce3f66 100644 --- a/src/messaging/messaging_api.js +++ b/src/messaging/messaging_api.js @@ -711,6 +711,10 @@ MessageService.prototype.sendMessage = function () { {name: 'simIndex', type: types_.LONG, optional: true, nullable: true} ]); + if (args.message.type != this.type) { + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR); + } + var self = this; bridge.async({ cmd: 'MessageService_sendMessage', @@ -753,6 +757,10 @@ MessageService.prototype.loadMessageBody = function () { {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} ]); + if (args.message.type != this.type) { + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR); + } + var self = this; bridge.async({ @@ -936,6 +944,10 @@ MessageStorage.prototype.addDraftMessage = function () { {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} ]); + if (args.message.type != this.service.type) { + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR); + } + var self = this; bridge.async({ cmd: 'MessageStorage_addDraftMessage', @@ -1020,13 +1032,19 @@ MessageStorage.prototype.findMessages = function () { MessageStorage.prototype.removeMessages = function () { var args = validator_.validateArgs(arguments, [ - {name: 'messages', type: types_.ARRAY}, + {name: 'messages', type: types_.ARRAY, values: Message}, {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} ]); var self = this; + args.messages.forEach(function(msg) { + if (msg.type != self.service.type) { + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR); + } + }); + bridge.async({ cmd: 'MessageStorage_removeMessages', args: { @@ -1053,13 +1071,19 @@ MessageStorage.prototype.removeMessages = function () { MessageStorage.prototype.updateMessages = function () { var args = validator_.validateArgs(arguments, [ - {name: 'messages', type: types_.ARRAY}, + {name: 'messages', type: types_.ARRAY, values: Message}, {name: 'successCallback', type: types_.FUNCTION, optional: true, nullable: true}, {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true} ]); var self = this; + args.messages.forEach(function(msg) { + if (msg.type != self.service.type) { + throw new tizen.WebAPIException(tizen.WebAPIException.TYPE_MISMATCH_ERR); + } + }); + bridge.async({ cmd: 'MessageStorage_updateMessages', args: { @@ -1510,4 +1534,4 @@ tizen.Message = Message; tizen.MessageAttachment = MessageAttachment; -exports = new Messaging(); \ No newline at end of file +exports = new Messaging(); diff --git a/src/messaging/messaging_database_manager.cc b/src/messaging/messaging_database_manager.cc index 479e049d..21360cd6 100755 --- a/src/messaging/messaging_database_manager.cc +++ b/src/messaging/messaging_database_manager.cc @@ -355,8 +355,8 @@ std::string MessagingDatabaseManager::getMatchString(tizen::AnyPtr match_value, } } -std::string MessagingDatabaseManager::getAttributeFilterQuery(AbstractFilterPtr filter, - AttributeInfoMap& attribute_map, MessageType msgType) +PlatformResult MessagingDatabaseManager::getAttributeFilterQuery(AbstractFilterPtr filter, + AttributeInfoMap& attribute_map, MessageType msgType, std::string* result) { LoggerD("Entered"); @@ -364,7 +364,8 @@ std::string MessagingDatabaseManager::getAttributeFilterQuery(AbstractFilterPtr AttributeFilterPtr attr_filter = castToAttributeFilter(filter); if(!attr_filter) { LoggerE("passed filter is not valid AttributeFilter!"); - throw UnknownException("Wrong filter type - not attribute filter"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Wrong filter type - not attribute filter"); } const std::string attribute_name = attr_filter->getAttributeName(); @@ -374,7 +375,8 @@ std::string MessagingDatabaseManager::getAttributeFilterQuery(AbstractFilterPtr sqlQuery << "(" << attribute_map[attribute_name].sql_name << " "; } else { LoggerE("The attribute: %s does not exist.", attribute_name.c_str()); - throw InvalidValuesException("The attribute does not exist."); + return PlatformResult(ErrorCode::INVALID_VALUES_ERR, + "The attribute does not exist."); } AnyPtr match_value_any_ptr = attr_filter->getMatchValue(); @@ -418,7 +420,8 @@ std::string MessagingDatabaseManager::getAttributeFilterQuery(AbstractFilterPtr "msgType:%d does not match SMS(%d), MMS(%d) nor EMAIL(%d)!", match_value.c_str(), msgType, MessageType::SMS, MessageType::MMS, MessageType::EMAIL); - throw UnknownException("The value does not match service type."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "The value does not match service type."); } } else if ("isRead" == attribute_name || "hasAttachment" == attribute_name) { @@ -507,7 +510,8 @@ std::string MessagingDatabaseManager::getAttributeFilterQuery(AbstractFilterPtr break; } default: - throw UnknownException("The match flag is incorrect."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "The match flag is incorrect."); } if (MessageType::SMS == msgType || MessageType::MMS == msgType) { @@ -524,11 +528,12 @@ std::string MessagingDatabaseManager::getAttributeFilterQuery(AbstractFilterPtr } } sqlQuery << ") "; - return sqlQuery.str(); + *result = sqlQuery.str(); + return PlatformResult(ErrorCode::NO_ERROR); } -std::string MessagingDatabaseManager::getAttributeRangeFilterQuery(AbstractFilterPtr filter, - AttributeInfoMap& attribute_map, MessageType msg_type) +PlatformResult MessagingDatabaseManager::getAttributeRangeFilterQuery(AbstractFilterPtr filter, + AttributeInfoMap& attribute_map, MessageType msg_type, std::string* result) { LoggerD("Entered"); @@ -538,7 +543,8 @@ std::string MessagingDatabaseManager::getAttributeRangeFilterQuery(AbstractFilte AttributeRangeFilterPtr attr_range_filter = castToAttributeRangeFilter(filter); if(!attr_range_filter) { LoggerE("passed filter is not valid AttributeRangeFilter!"); - throw UnknownException("Wrong filter type - not attribute range filter"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Wrong filter type - not attribute range filter"); } converter << attr_range_filter->getInitialValue()->toTimeT(); @@ -549,11 +555,12 @@ std::string MessagingDatabaseManager::getAttributeRangeFilterQuery(AbstractFilte sql_query << "(" << attribute_map[attr_range_filter->getAttributeName()].sql_name << " "; sql_query << "BETWEEN " << initial_value << " AND " << end_value << ") "; - return sql_query.str(); + *result = sql_query.str(); + return PlatformResult(ErrorCode::NO_ERROR); } -std::string MessagingDatabaseManager::getCompositeFilterQuery(AbstractFilterPtr filter, - AttributeInfoMap& attribute_map, MessageType msg_type) +PlatformResult MessagingDatabaseManager::getCompositeFilterQuery(AbstractFilterPtr filter, + AttributeInfoMap& attribute_map, MessageType msg_type, std::string* result) { LoggerD("Entered"); std::ostringstream sql_query; @@ -561,7 +568,8 @@ std::string MessagingDatabaseManager::getCompositeFilterQuery(AbstractFilterPtr CompositeFilterPtr comp_filter = castToCompositeFilter(filter); if(!comp_filter) { LoggerE("passed filter is not valid CompositeFilter!"); - throw UnknownException("Wrong filter type - not composite filter"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Wrong filter type - not composite filter"); } AbstractFilterPtrVector filters_arr = comp_filter->getFilters(); @@ -580,21 +588,31 @@ std::string MessagingDatabaseManager::getCompositeFilterQuery(AbstractFilterPtr const FilterType filter_type = filters_arr[i]->getFilterType(); switch (filter_type) { case ATTRIBUTE_FILTER: { - sql_query << getAttributeFilterQuery(filters_arr[i], attribute_map, msg_type); - break; + std::string query; + PlatformResult ret = getAttributeFilterQuery(filters_arr[i], attribute_map, msg_type, &query); + if (ret.IsError()) return ret; + sql_query << query; + break; } case ATTRIBUTE_RANGE_FILTER: { - sql_query << getAttributeRangeFilterQuery(filters_arr[i], attribute_map, msg_type); - break; + std::string query; + PlatformResult ret = getAttributeRangeFilterQuery(filters_arr[i], attribute_map, msg_type, &query); + if (ret.IsError()) return ret; + sql_query << query; + break; } case COMPOSITE_FILTER: { - sql_query << getCompositeFilterQuery(filters_arr[i], attribute_map, msg_type); - break; + std::string query; + PlatformResult ret = getCompositeFilterQuery(filters_arr[i], attribute_map, msg_type, &query); + if (ret.IsError()) return ret; + sql_query << query; + break; } default: LoggerE("Error while querying message - unsupported filter type: %d", filter_type); - throw UnknownException("Error while querying message."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Error while querying message."); } if (i != (size - 1)) { @@ -603,12 +621,13 @@ std::string MessagingDatabaseManager::getCompositeFilterQuery(AbstractFilterPtr } sql_query << ") "; - return sql_query.str(); + *result = sql_query.str(); + return PlatformResult(ErrorCode::NO_ERROR); } -std::string MessagingDatabaseManager::addFilters(AbstractFilterPtr filter, +PlatformResult MessagingDatabaseManager::addFilters(AbstractFilterPtr filter, SortModePtr sort_mode, long limit, long offset, AttributeInfoMap& attribute_map, - MessageType msg_type) + MessageType msg_type, std::string* result) { LoggerD("Entered"); std::ostringstream sql_query; @@ -619,7 +638,7 @@ std::string MessagingDatabaseManager::addFilters(AbstractFilterPtr filter, sql_query << attribute_map["type"].sql_name << " = " << msg_type << " AND "; } else { LoggerE("The service type is incorrect - msg_type is UNDEFINED"); - throw UnknownException("The service type is incorrect."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "The service type is incorrect."); } } @@ -627,20 +646,29 @@ std::string MessagingDatabaseManager::addFilters(AbstractFilterPtr filter, // Filter query switch (filter->getFilterType()) { case ATTRIBUTE_FILTER: { - sql_query << getAttributeFilterQuery(filter, attribute_map, msg_type); - } break; - + std::string query; + PlatformResult ret = getAttributeFilterQuery(filter, attribute_map, msg_type, &query); + if (ret.IsError()) return ret; + sql_query << query; + break; + } case ATTRIBUTE_RANGE_FILTER: { - sql_query << getAttributeRangeFilterQuery(filter, attribute_map, msg_type); - } break; - + std::string query; + PlatformResult ret = getAttributeRangeFilterQuery(filter, attribute_map, msg_type, &query); + if (ret.IsError()) return ret; + sql_query << query; + break; + } case COMPOSITE_FILTER : { - sql_query << getCompositeFilterQuery(filter, attribute_map, msg_type); - } break; - + std::string query; + PlatformResult ret = getCompositeFilterQuery(filter, attribute_map, msg_type, &query); + if (ret.IsError()) return ret; + sql_query << query; + break; + } default: LoggerE("The filter type is incorrect: %d", filter->getFilterType()); - throw UnknownException("The filter type is incorrect."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "The filter type is incorrect."); } } @@ -651,7 +679,7 @@ std::string MessagingDatabaseManager::addFilters(AbstractFilterPtr filter, << attribute_map[sort_mode->getAttributeName()].sql_name << " "; } else { LoggerE("The attribute does not exist."); - throw UnknownException("The attribute does not exist."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "The attribute does not exist."); } if (ASC == sort_mode->getOrder()) { @@ -684,11 +712,12 @@ std::string MessagingDatabaseManager::addFilters(AbstractFilterPtr filter, sql_query << "OFFSET " << offset << " "; } - return sql_query.str(); + *result = sql_query.str(); + return PlatformResult(ErrorCode::NO_ERROR); } -std::vector MessagingDatabaseManager::findShortMessages( - FindMsgCallbackUserData* callback) +PlatformResult MessagingDatabaseManager::findShortMessages( + FindMsgCallbackUserData* callback, std::vector* result) { LoggerD("Entered"); std::ostringstream sqlQuery; @@ -710,14 +739,19 @@ std::vector MessagingDatabaseManager::findShortMessages( long offset = callback->getOffset(); MessageType msgType = callback->getMessageServiceType(); - sqlQuery << addFilters(filter, sortMode, limit, offset, m_msg_attr_map, msgType); + std::string filters_query; + PlatformResult ret = addFilters(filter, sortMode, limit, offset, m_msg_attr_map, + msgType, &filters_query); + if (ret.IsError()) return ret; + sqlQuery << filters_query; LoggerD("%s", sqlQuery.str().c_str()); // Getting results from database msg_error_t err = getTable(sqlQuery.str(), &results, &resultsCount); if (MSG_SUCCESS != err) { freeTable(&results); - throw UnknownException("Error while getting data from database."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Error while getting data from database."); } for (int i = 0; i < resultsCount; ++i) { @@ -726,11 +760,12 @@ std::vector MessagingDatabaseManager::findShortMessages( } freeTable(&results); - return messagesIds; + *result = messagesIds; + return PlatformResult(ErrorCode::NO_ERROR); } -std::pair MessagingDatabaseManager::findEmails( - FindMsgCallbackUserData* callback) +PlatformResult MessagingDatabaseManager::findEmails( + FindMsgCallbackUserData* callback, std::pair* result) { LoggerD("Entered"); std::ostringstream sqlWhereClause; @@ -745,9 +780,13 @@ std::pair MessagingDatabaseManager::findEmails( MessageType msgType = callback->getMessageServiceType(); int accountId = callback->getAccountId(); + std::string filters_query; + PlatformResult ret = addFilters(filter, sortMode, limit, offset, + m_email_attr_map, msgType, &filters_query); + if (ret.IsError()) return ret; sqlWhereClause << "WHERE " << m_email_attr_map["serviceId"].sql_name << " = " << accountId << " AND " - << addFilters(filter, sortMode, limit, offset, m_email_attr_map, msgType); + << filters_query; LoggerD("%s", sqlWhereClause.str().c_str()); // Getting results from database @@ -759,15 +798,17 @@ std::pair MessagingDatabaseManager::findEmails( if (EMAIL_ERROR_MAIL_NOT_FOUND == err) { resultsCount = 0; } else { - throw UnknownException("Error while getting data from database."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Error while getting data from database."); } } - return std::make_pair(resultsCount, results); + *result = std::make_pair(resultsCount, results); + return PlatformResult(ErrorCode::NO_ERROR); } -std::vector MessagingDatabaseManager::findShortMessageConversations( - ConversationCallbackData* callback) +PlatformResult MessagingDatabaseManager::findShortMessageConversations( + ConversationCallbackData* callback, std::vector* result) { LoggerD("Entered"); std::ostringstream sqlQuery; @@ -792,14 +833,19 @@ std::vector MessagingDatabaseManager::findShortMessageConversations( long offset = callback->getOffset(); MessageType msgType = callback->getMessageServiceType(); - sqlQuery << addFilters(filter, sortMode, limit, offset, m_msg_conv_attr_map, msgType); + std::string filters_query; + PlatformResult ret = addFilters(filter, sortMode, limit, offset, m_msg_conv_attr_map, + msgType, &filters_query); + if (ret.IsError()) return ret; + sqlQuery << filters_query; LoggerD("%s", sqlQuery.str().c_str()); // Getting results from database msg_error_t err = getTable(sqlQuery.str(), &results, &resultsCount); if (MSG_SUCCESS != err) { freeTable(&results); - throw common::UnknownException("Error while getting data from database."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Error while getting data from database."); } for (int i = 0; i < resultsCount; ++i) { @@ -808,11 +854,12 @@ std::vector MessagingDatabaseManager::findShortMessageConversations( } freeTable(&results); - return conversationsIds; + *result = conversationsIds; + return PlatformResult(ErrorCode::NO_ERROR); } -std::vector MessagingDatabaseManager::findEmailConversations( - ConversationCallbackData* callback) +PlatformResult MessagingDatabaseManager::findEmailConversations( + ConversationCallbackData* callback, std::vector* result) { LoggerD("Entered"); std::ostringstream sqlWhereClause; @@ -829,9 +876,13 @@ std::vector MessagingDatabaseManager::findEmailConversati MessageType msgType = callback->getMessageServiceType(); int accountId = callback->getAccountId(); + std::string filters_query; + PlatformResult ret = addFilters(filter, sortMode, limit, offset, m_email_conv_attr_map, + msgType, &filters_query); + if (ret.IsError()) return ret; sqlWhereClause << "WHERE " << m_email_conv_attr_map["serviceId"].sql_name << " = " << accountId << " AND " - << addFilters(filter, sortMode, limit, offset, m_email_conv_attr_map, msgType); + << filters_query; LoggerD("%s", sqlWhereClause.str().c_str()); // Getting results from database @@ -843,7 +894,8 @@ std::vector MessagingDatabaseManager::findEmailConversati if (EMAIL_ERROR_MAIL_NOT_FOUND == err) { resultsCount = 0; } else { - throw UnknownException("Error while getting data from database."); + return PlatformResult(ErrorCode::UNKNOWN_ERR, + "Error while getting data from database."); } } @@ -867,7 +919,8 @@ std::vector MessagingDatabaseManager::findEmailConversati } email_free_mail_data(&results, resultsCount); - return conversationsInfo; + *result = conversationsInfo; + return PlatformResult(ErrorCode::NO_ERROR); } } // Messaging diff --git a/src/messaging/messaging_database_manager.h b/src/messaging/messaging_database_manager.h index b3d54409..f3516b34 100755 --- a/src/messaging/messaging_database_manager.h +++ b/src/messaging/messaging_database_manager.h @@ -29,6 +29,7 @@ #include #include "MsgCommon/AbstractFilter.h" +#include "common/platform_result.h" #include "find_msg_callback_user_data.h" //#include "ConversationCallbackData.h" @@ -81,10 +82,13 @@ struct EmailConversationInfo { class MessagingDatabaseManager { public: static MessagingDatabaseManager& getInstance(); - std::vector findShortMessages(FindMsgCallbackUserData* callback); - std::pair findEmails(FindMsgCallbackUserData* callback); - std::vector findShortMessageConversations(ConversationCallbackData* callback); - std::vector findEmailConversations(ConversationCallbackData* callback); + common::PlatformResult findShortMessages(FindMsgCallbackUserData* callback, std::vector* result); + common::PlatformResult findEmails(FindMsgCallbackUserData* callback, + std::pair* result); + common::PlatformResult findShortMessageConversations(ConversationCallbackData* callback, + std::vector* result); + common::PlatformResult findEmailConversations(ConversationCallbackData* callback, + std::vector* result); private: MessagingDatabaseManager(); @@ -99,14 +103,16 @@ private: int cellToInt(char** array, int cellId); std::string getMatchString(tizen::AnyPtr matchValue, const tizen::PrimitiveType type) const; - std::string getAttributeFilterQuery(tizen::AbstractFilterPtr filter, - AttributeInfoMap& attributeMap, MessageType msgType); - std::string getAttributeRangeFilterQuery(tizen::AbstractFilterPtr filter, - AttributeInfoMap& attributeMap, MessageType msgType); - std::string getCompositeFilterQuery(tizen::AbstractFilterPtr filter, - AttributeInfoMap& attributeMap, MessageType msgType); - std::string addFilters(tizen::AbstractFilterPtr filter, tizen::SortModePtr sortMode, - long limit, long offset, AttributeInfoMap& attributeMap, MessageType msgType); + common::PlatformResult getAttributeFilterQuery(tizen::AbstractFilterPtr filter, + AttributeInfoMap& attributeMap, MessageType msgType, std::string* result); + common::PlatformResult getAttributeRangeFilterQuery(tizen::AbstractFilterPtr filter, + AttributeInfoMap& attributeMap, MessageType msgType, std::string* result); + common::PlatformResult getCompositeFilterQuery(tizen::AbstractFilterPtr filter, + AttributeInfoMap& attributeMap, MessageType msgType, std::string* result); + common::PlatformResult addFilters(tizen::AbstractFilterPtr filter, + tizen::SortModePtr sortMode, long limit, long offset, + AttributeInfoMap& attributeMap, MessageType msgType, + std::string* result); AttributeInfoMap m_msg_attr_map; AttributeInfoMap m_email_attr_map; diff --git a/src/messaging/messaging_extension.cc b/src/messaging/messaging_extension.cc index 8f830428..cde1127d 100644 --- a/src/messaging/messaging_extension.cc +++ b/src/messaging/messaging_extension.cc @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "common/logger.h" #include "messaging_extension.h" #include "messaging_instance.h" +#include "email_manager.h" namespace { const char* kMessaging = "tizen.messaging"; @@ -13,6 +15,8 @@ namespace { // This will be generated from messaging_api.js. extern const char kSource_messaging_api[]; +using namespace common; + common::Extension* CreateExtension() { return new MessagingExtension; } @@ -31,5 +35,11 @@ MessagingExtension::MessagingExtension() { MessagingExtension::~MessagingExtension() {} common::Instance* MessagingExtension::CreateInstance() { + LoggerD("Entered"); + PlatformResult ret = extension::messaging::EmailManager::InitializeEmailService(); + if (ret.IsError()) { + LoggerE("Initializing the email service failed (%s)", ret.message().c_str()); + return nullptr; + } return &extension::messaging::MessagingInstance::getInstance(); } diff --git a/src/messaging/messaging_instance.cc b/src/messaging/messaging_instance.cc index eb2e1898..f3c01115 100644 --- a/src/messaging/messaging_instance.cc +++ b/src/messaging/messaging_instance.cc @@ -22,6 +22,9 @@ #include "message_storage.h" #include "message.h" +using common::ErrorCode; +using common::PlatformResult; + namespace extension { namespace messaging { @@ -162,17 +165,35 @@ MessagingInstance::~MessagingInstance() LoggerD("Entered"); } +#define POST_AND_RETURN(ret, json, obj, action) \ + picojson::object args; \ + ReportError(ret, &args); \ + obj[JSON_DATA] = picojson::value(args); \ + obj[JSON_ACTION] = picojson::value(action); \ + PostQueue::getInstance().addAndResolve( \ + obj.at(JSON_CALLBACK_ID).get(), \ + PostPriority::HIGH, \ + json->serialize() \ + ); \ + return; + void MessagingInstance::GetMessageServices(const picojson::value& args, - picojson::object& out) + picojson::object& out) { - LoggerD("Entered"); - - picojson::object data = args.get(JSON_DATA).get(); - picojson::value serviceTag = data.at(GET_MESSAGE_SERVICES_ARGS_MESSAGE_SERVICE_TYPE); - const double callbackId = args.get(JSON_CALLBACK_ID).get(); - - // above values should be validated in js - MessagingManager::getInstance().getMessageServices(serviceTag.to_str(), callbackId); + LoggerD("Entered"); + + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + + picojson::value data = args.get(JSON_DATA); + picojson::value serviceTag = data.get(). + at(GET_MESSAGE_SERVICES_ARGS_MESSAGE_SERVICE_TYPE); + const double callbackId = args.get(JSON_CALLBACK_ID).get(); + // above values should be validated in js + MessagingManager::getInstance().getMessageServices(serviceTag.to_str(), callbackId); } void MessagingInstance::MessageServiceSendMessage(const picojson::value& args, @@ -180,37 +201,51 @@ void MessagingInstance::MessageServiceSendMessage(const picojson::value& args, { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); picojson::value v_message = data.at(SEND_MESSAGE_ARGS_MESSAGE); const double callbackId = args.get(JSON_CALLBACK_ID).get(); - MessageRecipientsCallbackData* callback = new MessageRecipientsCallbackData(); - callback->setMessage(MessagingUtil::jsonToMessage(v_message)); - int serviceId = getServiceIdFromJSON(data); - callback->setAccountId(serviceId); - auto json = std::shared_ptr(new picojson::value(picojson::object())); picojson::object& obj = json->get(); obj[JSON_CALLBACK_ID] = picojson::value(callbackId); - auto simIndex = static_cast - (MessagingUtil::getValueFromJSONObject(data,SEND_MESSAGE_ARGS_SIMINDEX)); - - if (!callback->setSimIndex(simIndex)) { - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - delete callback; - callback = NULL; - return; + std::shared_ptr message; + PlatformResult ret = MessagingUtil::jsonToMessage(v_message, &message); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) } + MessageRecipientsCallbackData* callback = new MessageRecipientsCallbackData(); + long simIndex = 0; + int serviceId = 0; + callback->setJson(json); + callback->setMessage(message); + serviceId = getServiceIdFromJSON(data); + callback->setAccountId(serviceId); + simIndex = static_cast + (MessagingUtil::getValueFromJSONObject(data,SEND_MESSAGE_ARGS_SIMINDEX)); + + if (!callback->setSimIndex(simIndex)) { + delete callback; + callback = nullptr; + POST_AND_RETURN(PlatformResult(ErrorCode::UNKNOWN_ERR, "set sim index failed"), + json, obj, JSON_CALLBACK_ERROR) + } PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); auto service = MessagingManager::getInstance().getMessageService(serviceId); - service->sendMessage(callback); + + ret = service->sendMessage(callback); + if (!ret) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } } void MessagingInstance::MessageServiceLoadMessageBody(const picojson::value& args, @@ -218,22 +253,38 @@ void MessagingInstance::MessageServiceLoadMessageBody(const picojson::value& arg { LoggerD("Entered"); - picojson::object data = args.get(JSON_DATA).get(); - picojson::value message = data.at(ADD_DRAFT_MESSAGE_ARGS_MESSAGE); - const double callbackId = args.get(JSON_CALLBACK_ID).get(); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); - MessageBodyCallbackData* callback = new MessageBodyCallbackData(); - callback->setMessage(MessagingUtil::jsonToMessage(message)); + picojson::value json_message = data.at(ADD_DRAFT_MESSAGE_ARGS_MESSAGE); + const double callbackId = args.get(JSON_CALLBACK_ID).get(); auto json = std::shared_ptr(new picojson::value(picojson::object())); picojson::object& obj = json->get(); obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + std::shared_ptr message; + PlatformResult ret = MessagingUtil::jsonToMessage(json_message, &message); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } + + MessageBodyCallbackData* callback = new MessageBodyCallbackData(); + callback->setJson(json); + callback->setMessage(message); PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); auto service = MessagingManager::getInstance().getMessageService(getServiceIdFromJSON(data)); - service->loadMessageBody(callback); + ret = service->loadMessageBody(callback); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } } void MessagingInstance::MessageServiceLoadMessageAttachment(const picojson::value& args, @@ -241,6 +292,12 @@ void MessagingInstance::MessageServiceLoadMessageAttachment(const picojson::valu { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); picojson::value attachment = data.at(LOAD_MESSAGE_ATTACHMENT_ARGS_ATTACHMENT); const double callbackId = args.get(JSON_CALLBACK_ID).get(); @@ -255,7 +312,10 @@ void MessagingInstance::MessageServiceLoadMessageAttachment(const picojson::valu PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); auto service = MessagingManager::getInstance().getMessageService(getServiceIdFromJSON(data)); - service->loadMessageAttachment(callback); + const auto result = service->loadMessageAttachment(callback); + if (result.IsError()) { + POST_AND_RETURN(result, json, obj, JSON_CALLBACK_ERROR) + } } void MessagingInstance::MessageServiceSync(const picojson::value& args, @@ -263,17 +323,24 @@ void MessagingInstance::MessageServiceSync(const picojson::value& args, { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); picojson::value v_id = data.at(SYNC_ARGS_ID); picojson::value v_limit = data.at(SYNC_ARGS_LIMIT); const double callbackId = args.get(JSON_CALLBACK_ID).get(); int id = -1; - try{ + try { id = std::stoi(v_id.get()); } catch(...) { LoggerE("Problem with MessageService"); - throw common::UnknownException("Problem with MessageService"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out); + return; } long limit = 0; if (v_limit.is()) { @@ -290,10 +357,15 @@ void MessagingInstance::MessageServiceSync(const picojson::value& args, callback->setLimit(limit); PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); - long op_id = MessagingManager::getInstance().getMessageService(id)->sync(callback); + long op_id = -1; + + const auto result = MessagingManager::getInstance().getMessageService(id)->sync(callback, &op_id); - picojson::value v_op_id(static_cast(op_id)); - ReportSuccess(v_op_id, out); + if (result) { + ReportSuccess(picojson::value(static_cast(op_id)), out); + } else { + ReportError(result, &out); + } } void MessagingInstance::MessageServiceSyncFolder(const picojson::value& args, @@ -301,6 +373,12 @@ void MessagingInstance::MessageServiceSyncFolder(const picojson::value& args, { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); picojson::value v_id = data.at(SYNC_FOLDER_ARGS_ID); picojson::value v_folder = data.at(SYNC_FOLDER_ARGS_FOLDER); @@ -308,11 +386,12 @@ void MessagingInstance::MessageServiceSyncFolder(const picojson::value& args, const double callbackId = args.get(JSON_CALLBACK_ID).get(); int id = -1; - try{ + try { id = std::stoi(v_id.get()); } catch(...) { LoggerE("Problem with MessageService"); - throw common::UnknownException("Problem with MessageService"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out); + return; } long limit = 0; @@ -331,10 +410,14 @@ void MessagingInstance::MessageServiceSyncFolder(const picojson::value& args, callback->setLimit(limit); PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); - long op_id = MessagingManager::getInstance().getMessageService(id)->syncFolder(callback); + long op_id = -1; - picojson::value v_op_id(static_cast(op_id)); - ReportSuccess(v_op_id, out); + const auto result = MessagingManager::getInstance().getMessageService(id)->syncFolder(callback, &op_id); + if (result) { + ReportSuccess(picojson::value(static_cast(op_id)), out); + } else { + ReportError(result, &out); + } } void MessagingInstance::MessageServiceStopSync(const picojson::value& args, @@ -342,30 +425,43 @@ void MessagingInstance::MessageServiceStopSync(const picojson::value& args, { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); - if(data.find(STOP_SYNC_ARGS_ID) != data.end()){ + + if (data.find(STOP_SYNC_ARGS_ID) != data.end()) { picojson::value v_id = data.at(STOP_SYNC_ARGS_ID); picojson::value v_op_id = data.at(STOP_SYNC_ARGS_OPID); int id = -1; - try{ + try { id = std::stoi(v_id.get()); - } catch(...){ + } catch(...) { LoggerD("Problem with MessageService"); - throw common::UnknownException("Problem with MessageService"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out); + return; } long op_id = 0; if (v_op_id.is()) { op_id = static_cast(v_op_id.get()); } - MessagingManager::getInstance().getMessageService(id)->stopSync(op_id); + + const auto result = MessagingManager::getInstance().getMessageService(id)->stopSync(op_id); + + if (result) { + ReportSuccess(out); + } else { + ReportError(result, &out); + } } else { LoggerE("Unknown error"); - throw common::UnknownException("Unknown error"); + ReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out); } - - ReportSuccess(out); } void MessagingInstance::MessageStorageAddDraft(const picojson::value& args, @@ -373,19 +469,32 @@ void MessagingInstance::MessageStorageAddDraft(const picojson::value& args, { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); picojson::value v_message = data.at(ADD_DRAFT_MESSAGE_ARGS_MESSAGE); const double callbackId = args.get(JSON_CALLBACK_ID).get(); + auto json = std::shared_ptr(new picojson::value(picojson::object())); + picojson::object& obj = json->get(); + obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + std::shared_ptr message; + PlatformResult ret = MessagingUtil::jsonToMessage(v_message, &message); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } + MessageCallbackUserData* callback = new MessageCallbackUserData(); - callback->setMessage(MessagingUtil::jsonToMessage(v_message)); + callback->setMessage(message); int serviceId = getServiceIdFromJSON(data); callback->setAccountId(serviceId); - auto json = std::shared_ptr(new picojson::value(picojson::object())); - picojson::object& obj = json->get(); - obj[JSON_CALLBACK_ID] = picojson::value(callbackId); callback->setJson(json); PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); @@ -398,11 +507,24 @@ void MessagingInstance::MessageStorageFindMessages(const picojson::value& args, { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); const double callbackId = args.get(JSON_CALLBACK_ID).get(); - // TODO add support to CompositeFilter - auto filter = MessagingUtil::jsonToAbstractFilter(data); + auto json = std::shared_ptr(new picojson::value(picojson::object())); + picojson::object& obj = json->get(); + obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + AbstractFilterPtr filter; + PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } auto sortMode = MessagingUtil::jsonToSortMode(data); long limit = static_cast @@ -420,10 +542,6 @@ void MessagingInstance::MessageStorageFindMessages(const picojson::value& args, callback->setOffset(offset); callback->setAccountId(serviceId); callback->setSortMode(sortMode); - - auto json = std::shared_ptr(new picojson::value(picojson::object())); - picojson::object& obj = json->get(); - obj[JSON_CALLBACK_ID] = picojson::value(callbackId); callback->setJson(json); PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); @@ -434,6 +552,13 @@ void MessagingInstance::MessageStorageRemoveMessages(const picojson::value& args picojson::object& out) { LoggerD("Entered"); + + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); picojson::array messages = data.at(REMOVE_MESSAGES_ARGS_MESSAGES).get(); const double callbackId = args.get(JSON_CALLBACK_ID).get(); @@ -441,7 +566,11 @@ void MessagingInstance::MessageStorageRemoveMessages(const picojson::value& args MessagesCallbackUserData* callback = new MessagesCallbackUserData(); auto each = [callback] (picojson::value& v)->void { - callback->addMessage(MessagingUtil::jsonToMessage(v)); + std::shared_ptr message; + PlatformResult ret = MessagingUtil::jsonToMessage(v, &message); + if (ret.IsSuccess()) { + callback->addMessage(message); + } }; for_each(messages.begin(), messages.end(), each); @@ -462,6 +591,12 @@ void MessagingInstance::MessageStorageUpdateMessages(const picojson::value& args { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); picojson::value pico_messages = data.at(UPDATE_MESSAGES_ARGS_MESSAGES); auto pico_array = pico_messages.get(); @@ -471,7 +606,11 @@ void MessagingInstance::MessageStorageUpdateMessages(const picojson::value& args std::vector> messages; std::for_each(pico_array.begin(), pico_array.end(), [&callback](picojson::value& v)->void { - callback->addMessage(MessagingUtil::jsonToMessage(v)); + std::shared_ptr message; + PlatformResult ret = MessagingUtil::jsonToMessage(v, &message); + if (ret.IsSuccess()) { + callback->addMessage(message); + } }); auto json = std::shared_ptr(new picojson::value(picojson::object())); @@ -490,11 +629,24 @@ void MessagingInstance::MessageStorageFindConversations(const picojson::value& a { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); const double callbackId = args.get(JSON_CALLBACK_ID).get(); - // TODO add support to CompositeFilter - auto filter = MessagingUtil::jsonToAbstractFilter(data); + auto json = std::shared_ptr(new picojson::value(picojson::object())); + picojson::object& obj = json->get(); + obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + AbstractFilterPtr filter; + PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } auto sortMode = MessagingUtil::jsonToSortMode(data); long limit = static_cast (MessagingUtil::getValueFromJSONObject(data, FIND_CONVERSATIONS_ARGS_LIMIT)); @@ -509,10 +661,6 @@ void MessagingInstance::MessageStorageFindConversations(const picojson::value& a callback->setOffset(offset); callback->setAccountId(serviceId); callback->setSortMode(sortMode); - - auto json = std::shared_ptr(new picojson::value(picojson::object())); - picojson::object& obj = json->get(); - obj[JSON_CALLBACK_ID] = picojson::value(callbackId); callback->setJson(json); PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); @@ -524,20 +672,33 @@ void MessagingInstance::MessageStorageRemoveConversations(const picojson::value& picojson::object& out) { LoggerD("Entered"); + + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); picojson::array conversations = data.at(REMOVE_CONVERSATIONS_ARGS_CONVERSATIONS).get(); const double callbackId = args.get(JSON_CALLBACK_ID).get(); - ConversationCallbackData* callback = new ConversationCallbackData(); - - auto each = [callback] (picojson::value& v)->void { - callback->addConversation(MessagingUtil::jsonToMessageConversation(v)); - }; - for_each(conversations.begin(), conversations.end(), each); - auto json = std::shared_ptr(new picojson::value(picojson::object())); picojson::object& obj = json->get(); obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + ConversationCallbackData* callback = new ConversationCallbackData(); + + PlatformResult ret(ErrorCode::NO_ERROR); + for (auto it = conversations.begin(); it != conversations.end(); ++it) { + std::shared_ptr conversation; + ret = MessagingUtil::jsonToMessageConversation(*it, &conversation); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } + callback->addConversation(conversation); + } + callback->setJson(json); auto service = MessagingManager::getInstance().getMessageService(getServiceIdFromJSON(data)); @@ -551,16 +712,27 @@ void MessagingInstance::MessageStorageFindFolders(const picojson::value& args, { LoggerD("Entered"); + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); const double callbackId = args.get(JSON_CALLBACK_ID).get(); - // TODO add support to CompositeFilter - auto filter = MessagingUtil::jsonToAbstractFilter(data); - FoldersCallbackData* callback = new FoldersCallbackData(); - callback->setFilter(filter); auto json = std::shared_ptr(new picojson::value(picojson::object())); picojson::object& obj = json->get(); obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + AbstractFilterPtr filter; + PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } + + FoldersCallbackData* callback = new FoldersCallbackData(); + callback->setFilter(filter); callback->setJson(json); PostQueue::getInstance().add(static_cast(callbackId), PostPriority::HIGH); @@ -572,17 +744,34 @@ void MessagingInstance::MessageStorageAddMessagesChangeListener(const picojson:: picojson::object& out) { LoggerD("Entered"); + + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); - const long callbackId = static_cast(args.get(JSON_CALLBACK_ID).get()); + const double callbackId = args.get(JSON_CALLBACK_ID).get(); + + auto json = std::shared_ptr(new picojson::value(picojson::object())); + picojson::object& obj = json->get(); + obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + AbstractFilterPtr filter; + PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } int serviceId = getServiceIdFromJSON(data); auto service = MessagingManager::getInstance().getMessageService(serviceId); std::shared_ptr callback(new MessagesChangeCallback( - callbackId, serviceId, service->getMsgServiceType())); + static_cast(callbackId), serviceId, service->getMsgServiceType())); - callback->setFilter(MessagingUtil::jsonToAbstractFilter(data)); + callback->setFilter(filter); long op_id = service->getMsgStorage()->addMessagesChangeListener(callback); @@ -594,17 +783,34 @@ void MessagingInstance::MessageStorageAddConversationsChangeListener(const picoj picojson::object& out) { LoggerD("Entered"); + + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); - const long callbackId = static_cast(args.get(JSON_CALLBACK_ID).get()); + const double callbackId = args.get(JSON_CALLBACK_ID).get(); + + auto json = std::shared_ptr(new picojson::value(picojson::object())); + picojson::object& obj = json->get(); + obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + AbstractFilterPtr filter; + PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } int serviceId = getServiceIdFromJSON(data); auto service = MessagingManager::getInstance().getMessageService(serviceId); std::shared_ptr callback(new ConversationsChangeCallback( - callbackId, serviceId, service->getMsgServiceType())); + static_cast(callbackId), serviceId, service->getMsgServiceType())); - callback->setFilter(MessagingUtil::jsonToAbstractFilter(data)); + callback->setFilter(filter); long op_id = service->getMsgStorage()->addConversationsChangeListener(callback); @@ -616,17 +822,34 @@ void MessagingInstance::MessageStorageAddFolderChangeListener(const picojson::va picojson::object& out) { LoggerD("Entered"); + + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); - const long callbackId = static_cast(args.get(JSON_CALLBACK_ID).get()); + const double callbackId = args.get(JSON_CALLBACK_ID).get(); + + auto json = std::shared_ptr(new picojson::value(picojson::object())); + picojson::object& obj = json->get(); + obj[JSON_CALLBACK_ID] = picojson::value(callbackId); + + AbstractFilterPtr filter; + PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter); + if (ret.IsError()) { + POST_AND_RETURN(ret, json, obj, JSON_CALLBACK_ERROR) + } int serviceId = getServiceIdFromJSON(data); auto service = MessagingManager::getInstance().getMessageService(serviceId); std::shared_ptr callback(new FoldersChangeCallback( - callbackId, serviceId, service->getMsgServiceType())); + static_cast(callbackId), serviceId, service->getMsgServiceType())); - callback->setFilter(MessagingUtil::jsonToAbstractFilter(data)); + callback->setFilter(filter); long op_id = service->getMsgStorage()->addFoldersChangeListener(callback); @@ -638,6 +861,13 @@ void MessagingInstance::MessageStorageRemoveChangeListener(const picojson::value picojson::object& out) { LoggerD("Entered"); + + if (!args.contains(JSON_DATA) || !args.contains(JSON_CALLBACK_ID) || + !args.get(JSON_CALLBACK_ID).is()) { + LoggerE("json is incorrect - missing required member"); + return; + } + picojson::object data = args.get(JSON_DATA).get(); const long watchId = static_cast( data.at(REMOVE_CHANGE_LISTENER_ARGS_WATCHID).get()); diff --git a/src/messaging/messaging_manager.cc b/src/messaging/messaging_manager.cc index 7d3a7db9..ae57ebd1 100755 --- a/src/messaging/messaging_manager.cc +++ b/src/messaging/messaging_manager.cc @@ -21,6 +21,9 @@ #include "short_message_manager.h" #include "messaging_util.h" +using common::ErrorCode; +using common::PlatformResult; + namespace extension { namespace messaging { @@ -82,135 +85,144 @@ static gboolean callbackCompleted(const std::shared_ptr& static void* getMsgServicesThread(const std::shared_ptr& user_data) { - LoggerD("Entered"); - - std::shared_ptr response = user_data->json; - picojson::object& obj = response->get(); - MessageType type = MessageType::UNDEFINED; - try { - type = MessagingUtil::stringToMessageType(response->get(JSON_DATA).get()); - - std::vector msgServices; - MessageService* messageService = NULL; - email_account_t* email_accounts = NULL; - int count = 0; - bool isSupported = false; - switch (type) { - case MessageType::SMS: - LoggerD("MessageService for SMS"); - { - if (user_data->sms_service->second) delete user_data->sms_service->second; - - MessageService* service = new(std::nothrow) MessageServiceShortMsg( - MessageServiceAccountId::SMS_ACCOUNT_ID, - MessageType::SMS); - if (!service) { - LoggerE("MessageService for SMS creation failed"); - throw common::UnknownException("MessageService for SMS creation failed"); - } - *(user_data->sms_service) = std::make_pair(service->getMsgServiceId(), service); - - // TODO FIXME - picojson::array array; - array.push_back(picojson::value(service->toPicoJS())); - obj[JSON_DATA] = picojson::value(array); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - service = NULL; - } - break; - case MessageType::MMS: - LoggerD("MessageService for MMS"); - { - if (user_data->mms_service->second) { - delete user_data->mms_service->second; - } - - MessageService* service = new(std::nothrow) MessageServiceShortMsg( - MessageServiceAccountId::MMS_ACCOUNT_ID, - MessageType::MMS); - if (!service) { - LoggerE("MessageService for MMS creation failed"); - throw common::UnknownException("MessageService for MMS creation failed"); - } - *(user_data->mms_service) = std::make_pair(service->getMsgServiceId(), service); - - picojson::array array; - array.push_back(picojson::value(service->toPicoJS())); - obj[JSON_DATA] = picojson::value(array); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - service = NULL; + LoggerD("Entered"); + + std::shared_ptr response = user_data->json; + picojson::object& obj = response->get(); + MessageType type = MessageType::UNDEFINED; + + auto platform_result = MessagingUtil::stringToMessageType(response->get(JSON_DATA).get(), &type); + + if (platform_result) { + switch (type) { + case MessageType::SMS: + LoggerD("MessageService for SMS"); + { + if (user_data->sms_service->second) { + delete user_data->sms_service->second; + } + + MessageService* service = MessageServiceShortMsg::GetSmsMessageService(); + + if (!service) { + LoggerE("MessageService for SMS creation failed"); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "MessageService for SMS creation failed"); + } else { + *(user_data->sms_service) = std::make_pair(service->getMsgServiceId(), service); + + // TODO FIXME + picojson::array array; + array.push_back(picojson::value(service->toPicoJS())); + obj[JSON_DATA] = picojson::value(array); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + // service is stored, so it cannot be deleted + service = nullptr; + } + } + break; + + case MessageType::MMS: + LoggerD("MessageService for MMS"); + { + if (user_data->mms_service->second) { + delete user_data->mms_service->second; + } + + MessageService* service = MessageServiceShortMsg::GetMmsMessageService(); + + if (!service) { + LoggerE("MessageService for MMS creation failed"); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "MessageService for SMS creation failed"); + } else { + *(user_data->mms_service) = std::make_pair(service->getMsgServiceId(), service); + + picojson::array array; + array.push_back(picojson::value(service->toPicoJS())); + obj[JSON_DATA] = picojson::value(array); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + // service is stored, so it cannot be deleted + service = nullptr; + } + } + break; + + case MessageType::EMAIL: + LoggerD("MessageService for EMAIL"); + { + email_account_t* email_accounts = nullptr; + int count = 0; + + // TODO FIXME need to work on readability of that case + if (email_get_account_list(&email_accounts, &count) != EMAIL_ERROR_NONE) { + LoggerE("Method failed: email_get_account_list()"); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Error during getting account list"); + } else { + std::vector msgServices; + + for (int i = 0; i < count && platform_result; ++i) { + std::string name = "["; + name += email_accounts[i].account_name; + name += "] "; + name += email_accounts[i].incoming_server_user_name; + LoggerD("Account[%d/%d] id: %d, name: %s", i, count, + email_accounts[i].account_id, name.c_str()); + + MessageService* service = new (std::nothrow) MessageServiceEmail(email_accounts[i].account_id, + name.c_str()); + if (!service) { + LoggerD("message service[%d] is NULL", i); + std::for_each(msgServices.begin(), msgServices.end(), + [](MessageService* service) { + delete service; + }); + msgServices.clear(); + LoggerE("MessageService for email creation failed"); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "MessageService for email creation failed"); + } else { + msgServices.push_back(service); + } + + // service is stored, so it cannot be deleted + service = nullptr; } - break; - case MessageType::EMAIL: - // TODO FIXME need to work on readability of that case - if (email_get_account_list(&email_accounts, &count) != EMAIL_ERROR_NONE) { - LoggerE("Method failed: email_get_account_list()"); - throw common::UnknownException("Error during getting account list"); - } - else { - std::stringstream stream_name; - for (int i = 0; i < count; ++i) { - stream_name << "[" << email_accounts[i].account_name - << "] " - << email_accounts[i].incoming_server_user_name; - LoggerD("Account[%d/%d] id: %d, name: %s", i, - count, email_accounts[i].account_id, stream_name.str().c_str()); - - messageService = new (std::nothrow) MessageServiceEmail( - email_accounts[i].account_id, stream_name.str()); - if (!messageService) { - LoggerD("message service[%d] is NULL", i); - unsigned int count_srvcs = msgServices.size(); - for (unsigned int j = 0; j < count_srvcs; ++j) { - delete msgServices.at(j); - } - msgServices.clear(); - LoggerE("MessageService for email creation failed"); - throw common::UnknownException("MessageService for email creation failed"); - break; - } - else { - msgServices.push_back(messageService); - } - messageService = NULL; - stream_name.str(""); - } - - std::map& email_services = *(user_data->services_map); - std::for_each(email_services.begin(), email_services.end(), + + email_free_account(&email_accounts, count); + + if (platform_result) { + std::map& email_services = *(user_data->services_map); + std::for_each(email_services.begin(), email_services.end(), [](std::pair el) { - delete el.second; - } - ); - email_services.clear(); - - std::vector response; - std::for_each(msgServices.begin(), msgServices.end(), - [&response, &email_services](MessageService* service) { + delete el.second; + }); + email_services.clear(); + + std::vector response; + std::for_each(msgServices.begin(), msgServices.end(), + [&response, &email_services](MessageService* service) { response.push_back(picojson::value(service->toPicoJS())); - email_services.insert( - std::pair( - service->getMsgServiceId(), - service)); - } - ); - obj[JSON_DATA] = picojson::value(response); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - } - break; - default: - LoggerE("Unsupported services type"); - throw common::UnknownException("Unsupported services type"); + email_services.insert(std::pair(service->getMsgServiceId(), service)); + }); + obj[JSON_DATA] = picojson::value(response); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + } + } } - } catch(const common::PlatformException& e) { - LoggerE("Unknown error"); - obj[JSON_DATA] = e.ToJSON(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + break; } - - return nullptr; + } else { + LoggerE("Unsupported service type"); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Unsupported service type"); + } + + if (!platform_result) { + LoggerE("Unknown error"); + obj[JSON_DATA] = platform_result.ToJSON(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + } + + return nullptr; } void MessagingManager::getMessageServices(const std::string& type, double callbackId) diff --git a/src/messaging/messaging_util.cc b/src/messaging/messaging_util.cc index 571759e7..284b9281 100644 --- a/src/messaging/messaging_util.cc +++ b/src/messaging/messaging_util.cc @@ -20,8 +20,12 @@ #include "common/logger.h" #include "common/platform_exception.h" +using common::ErrorCode; +using common::PlatformResult; + namespace extension { namespace messaging { +using namespace common; const char* JSON_ACTION = "action"; const char* JSON_CALLBACK_ID = "cid"; @@ -36,6 +40,7 @@ const char* JSON_DATA_MESSAGE_ATTACHMENT = "messageAttachment"; const char* JSON_DATA_RECIPIENTS = "recipients"; const char* JSON_ERROR_MESSAGE = "message"; const char* JSON_ERROR_NAME = "name"; +const char* JSON_ERROR_CODE = "code"; const char* MESSAGE_ATTRIBUTE_ID = "id"; const char* MESSAGE_ATTRIBUTE_OLD_ID = "oldId"; @@ -169,28 +174,37 @@ MessageFolderType MessagingUtil::stringToMessageFolderType(std::string type) return MessageFolderType::MESSAGE_FOLDER_TYPE_NOTSTANDARD; } -MessageType MessagingUtil::stringToMessageType(std::string str) +PlatformResult MessagingUtil::stringToMessageType(const std::string& str, MessageType* out) { - try { - return stringToTypeMap.at(str); - } - catch (const std::out_of_range& e) { - std::string exceptionMsg = "Not supported type: "; - exceptionMsg += str; - LoggerE("%s", exceptionMsg.c_str()); - throw common::TypeMismatchException(exceptionMsg.c_str()); - } + const auto it = stringToTypeMap.find(str); + + if (it == stringToTypeMap.end()) { + LoggerE("Not supported type: %s", str.c_str()); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Not supported type: " + str); + } else { + *out = it->second; + return PlatformResult(ErrorCode::NO_ERROR); + } } -std::string MessagingUtil::messageTypeToString(MessageType type) +common::PlatformResult MessagingUtil::messageTypeToString(MessageType type, std::string* out) { - try { - return typeToStringMap.at(type); - } - catch (const std::out_of_range& e) { - LoggerE("Invalid MessageType"); - throw common::TypeMismatchException("Invalid MessageType"); - } + const auto it = typeToStringMap.find(type); + + if (it == typeToStringMap.end()) { + LoggerE("Invalid MessageType: %d", type); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Invalid MessageType"); + } else { + *out = it->second; + return PlatformResult(ErrorCode::NO_ERROR); + } +} + +std::string MessagingUtil::messageTypeToString(MessageType type) { + std::string type_str; + PlatformResult platform_result = messageTypeToString(type, &type_str); + assert(platform_result); + return type_str; } std::string MessagingUtil::ltrim(const std::string& input) @@ -238,7 +252,7 @@ std::vector MessagingUtil::extractEmailAddresses( return extractedAddresses; } -std::string MessagingUtil::loadFileContentToString(const std::string& file_path) +PlatformResult MessagingUtil::loadFileContentToString(const std::string& file_path, std::string* result) { std::ifstream input_file; input_file.open(file_path, std::ios::in); @@ -252,12 +266,13 @@ std::string MessagingUtil::loadFileContentToString(const std::string& file_path) outString.assign((std::istreambuf_iterator(input_file)), std::istreambuf_iterator()); input_file.close(); - return outString; + *result = outString; } else { std::stringstream ss_error_msg; ss_error_msg << "Failed to open file: " << file_path; - throw common::IOException(ss_error_msg.str().c_str()); + return PlatformResult(ErrorCode::IO_ERR, ss_error_msg.str().c_str()); } + return PlatformResult(ErrorCode::NO_ERROR); } std::string MessagingUtil::messageStatusToString(MessageStatus status) { @@ -352,8 +367,7 @@ picojson::value MessagingUtil::messageToJson(std::shared_ptr message) message->is_folder_id_set() ? picojson::value(std::to_string(message->getFolderId())) : picojson::value(); - o[MESSAGE_ATTRIBUTE_TYPE] = - picojson::value(MessagingUtil::messageTypeToString(message->getType())); + o[MESSAGE_ATTRIBUTE_TYPE] = picojson::value(message->getTypeString()); o[MESSAGE_ATTRIBUTE_TIMESTAMP] = message->is_timestamp_set() ? picojson::value(static_cast(message->getTimestamp())) @@ -398,8 +412,7 @@ picojson::value MessagingUtil::conversationToJson(std::shared_ptrgetConversationId())); - o[MESSAGE_CONVERSATION_ATTRIBUTE_TYPE] = - picojson::value(MessagingUtil::messageTypeToString(conversation->getType())); + o[MESSAGE_CONVERSATION_ATTRIBUTE_TYPE] = picojson::value(conversation->getTypeString()); o[MESSAGE_CONVERSATION_ATTRIBUTE_TIMESTAMP] = picojson::value(static_cast(conversation->getTimestamp())); @@ -481,13 +494,19 @@ picojson::value MessagingUtil::folderToJson(std::shared_ptr folde return v; } -std::shared_ptr MessagingUtil::jsonToMessage(const picojson::value& json) +PlatformResult MessagingUtil::jsonToMessage(const picojson::value& json, + std::shared_ptr* result_message) { LoggerD("Entered"); std::shared_ptr message; picojson::object data = json.get(); std::string type = data.at("type").get(); - MessageType mtype = MessagingUtil::stringToMessageType(type); + MessageType mtype = UNDEFINED; + auto platform_result = MessagingUtil::stringToMessageType(type, &mtype); + + if (!platform_result) { + return platform_result; + } switch (mtype) { case MessageType::SMS: @@ -503,7 +522,8 @@ std::shared_ptr MessagingUtil::jsonToMessage(const picojson::value& jso } else { std::string mid = data.at(MESSAGE_ATTRIBUTE_ID).get(); int message_id = std::atoi(mid.c_str()); - message = Message::findShortMessageById(message_id); + platform_result = Message::findShortMessageById(message_id, &message); + if (!platform_result) return platform_result; } break; case MessageType::EMAIL: @@ -514,10 +534,12 @@ std::shared_ptr MessagingUtil::jsonToMessage(const picojson::value& jso if (EMAIL_ERROR_NONE != email_get_mail_data(mail_id, &mail)) { // TODO what should happen? LoggerE("Fatal error: message not found: %d!", mail_id); - throw common::TypeMismatchException("Failed to find specified email."); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, + "Failed to find specified email."); } else { - message = Message::convertPlatformEmailToObject(*mail); + platform_result = Message::convertPlatformEmailToObject(*mail, &message); email_free_mail_data(&mail,1); + if (!platform_result) return platform_result; } } else { message = std::shared_ptr(new MessageEmail()); @@ -579,8 +601,8 @@ std::shared_ptr MessagingUtil::jsonToMessage(const picojson::value& jso for_each(ma.begin(), ma.end(), arrayVectorAttachmentConverter); message->setMessageAttachments(attachments); - return message; - + *result_message = message; + return PlatformResult(ErrorCode::NO_ERROR); } std::shared_ptr MessagingUtil::jsonToMessageBody(const picojson::value& json) @@ -672,12 +694,10 @@ tizen::SortModePtr MessagingUtil::jsonToSortMode(const picojson::object& json) LoggerD("Entered"); using namespace tizen; - try{ - if (json.at(JSON_TO_SORT).is()) { - return SortModePtr(); - } - } catch(const std::out_of_range& e){ - return SortModePtr(); + const auto it = json.find(JSON_TO_SORT); + + if (json.end() == it || it->second.is()) { + return SortModePtr(); } auto dataSort = getValueFromJSONObject(json, JSON_TO_SORT); @@ -687,39 +707,43 @@ tizen::SortModePtr MessagingUtil::jsonToSortMode(const picojson::object& json) return SortModePtr(new SortMode(name, order)); } -tizen::AbstractFilterPtr MessagingUtil::jsonToAbstractFilter(const picojson::object& json) +PlatformResult MessagingUtil::jsonToAbstractFilter(const picojson::object& json, + tizen::AbstractFilterPtr* result) { LoggerD("Entered"); const auto it = json.find(JSON_TO_FILTER); if (json.end() == it || it->second.is()) { - return AbstractFilterPtr(); + *result = AbstractFilterPtr(); + return PlatformResult(ErrorCode::NO_ERROR); } - return jsonFilterToAbstractFilter(json.at(JSON_TO_FILTER).get()); + return jsonFilterToAbstractFilter(json.at(JSON_TO_FILTER).get(), result); } -tizen::AbstractFilterPtr MessagingUtil::jsonFilterToAbstractFilter(const picojson::object& filter) +PlatformResult MessagingUtil::jsonFilterToAbstractFilter(const picojson::object& filter, + tizen::AbstractFilterPtr* result) { const auto& type = filter.at(JSON_FILTER_TYPE).get(); if (JSON_FILTER_ATTRIBUTE_TYPE == type) { - return jsonFilterToAttributeFilter(filter); + + return jsonFilterToAttributeFilter(filter, result); } if (JSON_FILTER_ATTRIBUTE_RANGE_TYPE == type) { - return jsonFilterToAttributeRangeFilter(filter); + return jsonFilterToAttributeRangeFilter(filter, result); } if (JSON_FILTER_COMPOSITE_TYPE == type) { - return jsonFilterToCompositeFilter(filter); + return jsonFilterToCompositeFilter(filter, result); } LoggerE("Unsupported filter type: %s", type.c_str()); - throw common::TypeMismatchException("Unsupported filter type"); - return AbstractFilterPtr(); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Unsupported filter type"); } -tizen::AttributeFilterPtr MessagingUtil::jsonFilterToAttributeFilter(const picojson::object& filter) +PlatformResult MessagingUtil::jsonFilterToAttributeFilter(const picojson::object& filter, + tizen::AbstractFilterPtr* result) { LoggerD("Entered"); @@ -750,29 +774,33 @@ tizen::AttributeFilterPtr MessagingUtil::jsonFilterToAttributeFilter(const picoj } else { LoggerE("Filter name is not recognized: %s", matchFlagStr.c_str()); - throw common::TypeMismatchException("Filter name is not recognized"); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Filter name is not recognized"); } - auto attributePtr = AttributeFilterPtr(new AttributeFilter(name)); + auto attributePtr = new AttributeFilter(name); attributePtr->setMatchFlag(filterMatch); attributePtr->setMatchValue(AnyPtr(new Any(filter.at(JSON_TO_MATCH_VALUE)))); - return attributePtr; + (*result).reset(attributePtr); + return PlatformResult(ErrorCode::NO_ERROR); } -tizen::AttributeRangeFilterPtr MessagingUtil::jsonFilterToAttributeRangeFilter(const picojson::object& filter) +PlatformResult MessagingUtil::jsonFilterToAttributeRangeFilter(const picojson::object& filter, + tizen::AbstractFilterPtr* result) { LoggerD("Entered"); auto name = getValueFromJSONObject(filter, JSON_TO_ATTRIBUTE_NAME); - auto attributeRangePtr = tizen::AttributeRangeFilterPtr(new tizen::AttributeRangeFilter(name)); + auto attributeRangePtr = new tizen::AttributeRangeFilter(name); attributeRangePtr->setInitialValue(AnyPtr(new Any(filter.at(JSON_TO_INITIAL_VALUE)))); attributeRangePtr->setEndValue(AnyPtr(new Any(filter.at(JSON_TO_END_VALUE)))); - return attributeRangePtr; + (*result).reset(attributeRangePtr); + return PlatformResult(ErrorCode::NO_ERROR); } -tizen::CompositeFilterPtr MessagingUtil::jsonFilterToCompositeFilter(const picojson::object& filter) +PlatformResult MessagingUtil::jsonFilterToCompositeFilter(const picojson::object& filter, + tizen::AbstractFilterPtr* result) { LoggerD("Entered"); @@ -790,16 +818,21 @@ tizen::CompositeFilterPtr MessagingUtil::jsonFilterToCompositeFilter(const picoj } else { LoggerE("Composite filter type is not recognized: %s", type.c_str()); - throw common::TypeMismatchException("Composite filter type is not recognized"); + return PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, + "Composite filter type is not recognized"); } - CompositeFilterPtr compositeFilter{new CompositeFilter(filterType)}; + auto compositeFilter = new CompositeFilter(filterType); for (const auto& a : filter.at(JSON_TO_FILTER_ARRAY).get()) { - compositeFilter->addFilter(jsonFilterToAbstractFilter(a.get())); + AbstractFilterPtr filter; + PlatformResult ret = jsonFilterToAbstractFilter(a.get(), &filter); + if (ret.IsError()) return ret; + compositeFilter->addFilter(filter); } - return compositeFilter; + (*result).reset(compositeFilter); + return PlatformResult(ErrorCode::NO_ERROR); } std::shared_ptr MessagingUtil::jsonToMessageAttachment(const picojson::value& json) @@ -853,13 +886,17 @@ picojson::value MessagingUtil::messageAttachmentToJson(std::shared_ptr MessagingUtil::jsonToMessageConversation(const picojson::value& json) +PlatformResult MessagingUtil::jsonToMessageConversation(const picojson::value& json, + std::shared_ptr* result_conversation) { LoggerD("Entered"); std::shared_ptr conversation; picojson::object data = json.get(); std::string type = data.at("type").get(); - MessageType mtype = MessagingUtil::stringToMessageType(type); + MessageType mtype = UNDEFINED; + auto platform_result = MessagingUtil::stringToMessageType(type, &mtype); + + if (!platform_result) return platform_result; conversation = std::shared_ptr(new MessageConversation()); @@ -920,7 +957,8 @@ std::shared_ptr MessagingUtil::jsonToMessageConversation(co MESSAGE_CONVERSATION_ATTRIBUTE_LAST_MESSAGE_ID).c_str()); conversation->setLastMessageId(lastMessageId); - return conversation; + *result_conversation = conversation; + return PlatformResult(ErrorCode::NO_ERROR); } PostQueue& PostQueue::getInstance() diff --git a/src/messaging/messaging_util.h b/src/messaging/messaging_util.h index 632231c6..1ae51630 100644 --- a/src/messaging/messaging_util.h +++ b/src/messaging/messaging_util.h @@ -13,6 +13,7 @@ #include #include "common/logger.h" #include "common/picojson.h" +#include "common/platform_result.h" #include "MsgCommon/SortMode.h" #include "MsgCommon/AttributeFilter.h" @@ -20,6 +21,7 @@ #include "message_folder.h" #include "message_attachment.h" +#include "common/platform_result.h" namespace extension { namespace messaging { @@ -37,6 +39,7 @@ extern const char* JSON_DATA_MESSAGE_ATTACHMENT; extern const char* JSON_DATA_RECIPIENTS; extern const char* JSON_ERROR_MESSAGE; extern const char* JSON_ERROR_NAME; +extern const char* JSON_ERROR_CODE; extern const char* MESSAGE_ATTRIBUTE_ID; extern const char* MESSAGE_ATTRIBUTE_CONVERSATION_ID; @@ -110,8 +113,9 @@ class MessagingUtil { public: static std::string messageFolderTypeToString(MessageFolderType); static MessageFolderType stringToMessageFolderType(std::string type); - static MessageType stringToMessageType(std::string); - static std::string messageTypeToString(MessageType); + static common::PlatformResult stringToMessageType(const std::string& str, MessageType* out); + static common::PlatformResult messageTypeToString(MessageType type, std::string* out); + static std::string messageTypeToString(MessageType type); static std::string ltrim(const std::string& input); static std::string extractSingleEmailAddress(const std::string& address); static std::vector extractEmailAddresses( @@ -122,12 +126,15 @@ public: static picojson::value messageAttachmentToJson(std::shared_ptr attachment); static picojson::value conversationToJson(std::shared_ptr conversation); static picojson::value folderToJson(std::shared_ptr folder); - static std::shared_ptr jsonToMessage(const picojson::value& json); + static common::PlatformResult jsonToMessage(const picojson::value& json, + std::shared_ptr* result); static std::shared_ptr jsonToMessageBody(const picojson::value& json); static std::shared_ptr jsonToMessageFolder(const picojson::value& json); static tizen::SortModePtr jsonToSortMode(const picojson::object& json); - static tizen::AbstractFilterPtr jsonToAbstractFilter(const picojson::object& json); - static std::shared_ptr jsonToMessageConversation(const picojson::value& json); + static common::PlatformResult jsonToAbstractFilter(const picojson::object& json, + tizen::AbstractFilterPtr* result); + static common::PlatformResult jsonToMessageConversation(const picojson::value& json, + std::shared_ptr* result_conversation); static std::shared_ptr jsonToMessageAttachment(const picojson::value& json); template @@ -153,14 +160,18 @@ public: * std::string result = loadFileContentToString(...); * Reason: no copy constructor will be invoked on return. */ - static std::string loadFileContentToString(const std::string& file_path); + static common::PlatformResult loadFileContentToString(const std::string& file_path, std::string* result); static std::string messageStatusToString(MessageStatus status); private: - static tizen::AbstractFilterPtr jsonFilterToAbstractFilter(const picojson::object& json); - static tizen::AttributeFilterPtr jsonFilterToAttributeFilter(const picojson::object& json); - static tizen::AttributeRangeFilterPtr jsonFilterToAttributeRangeFilter(const picojson::object& json); - static tizen::CompositeFilterPtr jsonFilterToCompositeFilter(const picojson::object& json); + static common::PlatformResult jsonFilterToAbstractFilter(const picojson::object& json, + tizen::AbstractFilterPtr* result); + static common::PlatformResult jsonFilterToAttributeFilter(const picojson::object& json, + tizen::AbstractFilterPtr* result); + static common::PlatformResult jsonFilterToAttributeRangeFilter(const picojson::object& json, + tizen::AbstractFilterPtr* result); + static common::PlatformResult jsonFilterToCompositeFilter(const picojson::object& json, + tizen::AbstractFilterPtr* result); }; enum PostPriority { diff --git a/src/messaging/short_message_manager.cc b/src/messaging/short_message_manager.cc index 4ffe81dd..9c35bbcf 100644 --- a/src/messaging/short_message_manager.cc +++ b/src/messaging/short_message_manager.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include +#include #include #include #include @@ -20,6 +20,8 @@ #include "short_message_manager.h" +using common::ErrorCode; +using common::PlatformResult; namespace extension { namespace messaging { @@ -43,49 +45,40 @@ static gboolean sendMessageCompleteCB(void* data) return false; } - try { - if (callback->isError()) { - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); - } - else { - std::shared_ptr message = callback->getMessage(); + if (callback->isError()) { + PostQueue::getInstance().resolve( + callback->getJson()->get().at(JSON_CALLBACK_ID).get(), + callback->getJson()->serialize() + ); + callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); + } + else { + std::shared_ptr message = callback->getMessage(); - LoggerD("Calling success callback with: %d recipients", message->getTO().size()); + LoggerD("Calling success callback with: %d recipients", message->getTO().size()); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + auto json = callback->getJson(); + picojson::object& obj = json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - std::vector recipients; - auto addToRecipients = [&recipients](std::string& e)->void { - recipients.push_back(picojson::value(e)); - }; + std::vector recipients; + auto addToRecipients = [&recipients](std::string& e)->void { + recipients.push_back(picojson::value(e)); + }; - auto toVect = callback->getMessage()->getTO(); - std::for_each(toVect.begin(), toVect.end(), addToRecipients); + auto toVect = callback->getMessage()->getTO(); + std::for_each(toVect.begin(), toVect.end(), addToRecipients); - picojson::object data; - data[JSON_DATA_RECIPIENTS] = picojson::value(recipients); - data[JSON_DATA_MESSAGE] = MessagingUtil::messageToJson(message); - obj[JSON_DATA] = picojson::value(data); + picojson::object data; + data[JSON_DATA_RECIPIENTS] = picojson::value(recipients); + data[JSON_DATA_MESSAGE] = MessagingUtil::messageToJson(message); + obj[JSON_DATA] = picojson::value(data); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - callback->getMessage()->setMessageStatus(MessageStatus::STATUS_SENT); - } - } - catch (const common::PlatformException& err) { - LoggerE("Error while calling sendMessage callback: %s (%s)", - (err.name()).c_str(),(err.message()).c_str()); - } - catch (...) { - LoggerE("Unknown error when calling sendMessage callback."); + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); + callback->getMessage()->setMessageStatus(MessageStatus::STATUS_SENT); } delete callback; @@ -103,36 +96,29 @@ static gboolean addDraftMessageCompleteCB(void *data) return FALSE; } - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); - } else { - LoggerD("Calling success callback"); - - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - picojson::object args; - args[JSON_DATA_MESSAGE] = MessagingUtil::messageToJson(callback->getMessage()); - obj[JSON_DATA] = picojson::value(args); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const common::PlatformException& err) { - LoggerE("Error while calling addDraftMessage callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Unknown error when calling addDraftMessage callback."); + if (callback->isError()) { + LoggerD("Calling error callback"); + + PostQueue::getInstance().resolve( + callback->getJson()->get().at(JSON_CALLBACK_ID).get(), + callback->getJson()->serialize() + ); + callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); + } else { + LoggerD("Calling success callback"); + + auto json = callback->getJson(); + picojson::object& obj = json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + picojson::object args; + args[JSON_DATA_MESSAGE] = MessagingUtil::messageToJson(callback->getMessage()); + obj[JSON_DATA] = picojson::value(args); + + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); } delete callback; @@ -142,16 +128,19 @@ static gboolean addDraftMessageCompleteCB(void *data) } -void ShortMsgManager::addDraftMessagePlatform(std::shared_ptr message) +PlatformResult ShortMsgManager::addDraftMessagePlatform(std::shared_ptr message) { LoggerD("Add new message(%p)", message.get()); // Save platform msg to get ID - msg_struct_t platform_msg - = Message::convertPlatformShortMessageToStruct(message.get(), m_msg_handle); + msg_struct_t platform_msg = nullptr; + PlatformResult ret = Message::convertPlatformShortMessageToStruct(message.get(), + m_msg_handle, &platform_msg); + if (ret.IsError()) return ret; + if (NULL == platform_msg) { LoggerE("Failed to prepare platform message"); - throw common::UnknownException("Cannot prepare platform message"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot prepare platform message"); } msg_struct_t send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); @@ -161,7 +150,7 @@ void ShortMsgManager::addDraftMessagePlatform(std::shared_ptr message) LoggerE("Message(%p): Failed to add draft, error: %d", message.get(), msg_id); msg_release_struct(&send_opt); msg_release_struct(&platform_msg); - throw common::UnknownException("Cannot add message to draft"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot add message to draft"); } LoggerD("Message(%p): New message ID: %d", message.get(), msg_id); @@ -178,13 +167,12 @@ void ShortMsgManager::addDraftMessagePlatform(std::shared_ptr message) } else { LoggerE("Message(%p): Failed to get conv", message.get()); } - - Message* msgInfo = Message::convertPlatformShortMessageToObject( - platform_msg); - + Message* msgInfo = nullptr; + ret = Message::convertPlatformShortMessageToObject( + platform_msg, &msgInfo); + if (ret.IsError()) return ret; const int folderId = msgInfo->getFolderId(); message->setFolderId(folderId); - const time_t timestamp = msgInfo->getTimestamp(); message->setTimeStamp(timestamp); @@ -208,153 +196,163 @@ void ShortMsgManager::addDraftMessagePlatform(std::shared_ptr message) LoggerW("Platform message is already destroyed"); } delete msgInfo; + return PlatformResult(ErrorCode::NO_ERROR); } -void ShortMsgManager::sendMessage(MessageRecipientsCallbackData* callback) +PlatformResult ShortMsgManager::SendMessagePlatform(MessageRecipientsCallbackData* callback) { - LoggerD("Entered"); - - if(!callback){ - LoggerE("Callback is null"); - return; - } - - int msg_id; - Message* msgInfo = NULL; - msg_struct_t platform_msg = NULL; - msg_struct_t send_opt = NULL; - msg_struct_t msg_conv = NULL; - msg_struct_t req = NULL; - - try { - std::lock_guard lock(m_mutex); - - std::shared_ptr message = callback->getMessage(); - MessageStatus msg_status = message->getMessageStatus(); - int ret = MSG_ERR_UNKNOWN; - - // if it is draft message just send it - // in other case create new platform message - // add it to draft and finally send it - if (!( message->is_id_set() && MessageStatus::STATUS_DRAFT == msg_status)) { - LoggerD("Add message to draft"); - addDraftMessagePlatform(message); - } - - msg_id = message->getId(); - LoggerD("Message ID: %d", msg_id); - - platform_msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); - send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); - msg_conv = msg_create_struct(MSG_STRUCT_CONV_INFO); - ret = msg_get_message(m_msg_handle, msg_id, platform_msg, send_opt); - if (MSG_SUCCESS != ret) { - LoggerE("Failed to get platform message structure: %d", ret); - throw common::UnknownException("Cannot get platform Message structure"); - } - - // Send message - message->setMessageStatus(MessageStatus::STATUS_SENDING); - req = msg_create_struct(MSG_STRUCT_REQUEST_INFO); - msg_set_struct_handle(req, MSG_REQUEST_MESSAGE_HND, platform_msg); - - int req_id = -1; - ret = msg_get_int_value(req, MSG_REQUEST_REQUESTID_INT, &req_id); - if (MSG_SUCCESS != ret) { - LoggerE("Failed to get send request ID: %d", ret); - throw common::UnknownException("Failed to get send request ID"); - } - + std::lock_guard lock(m_mutex); + + PlatformResult platform_result(ErrorCode::NO_ERROR); + int msg_id; + Message* msgInfo = nullptr; + msg_struct_t platform_msg = nullptr; + msg_struct_t send_opt = nullptr; + msg_struct_t msg_conv = nullptr; + msg_struct_t req = nullptr; + + std::shared_ptr message = callback->getMessage(); + MessageStatus msg_status = message->getMessageStatus(); + int ret = MSG_ERR_UNKNOWN; + + // if it is draft message just send it + // in other case create new platform message + // add it to draft and finally send it + if (!( message->is_id_set() && MessageStatus::STATUS_DRAFT == msg_status)) { + LoggerD("Add message to draft"); + platform_result = addDraftMessagePlatform(message); + + } + if(platform_result.IsSuccess()) { + msg_id = message->getId(); + LoggerD("Message ID: %d", msg_id); + + platform_msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); + send_opt = msg_create_struct(MSG_STRUCT_SENDOPT); + msg_conv = msg_create_struct(MSG_STRUCT_CONV_INFO); + ret = msg_get_message(m_msg_handle, msg_id, platform_msg, send_opt); + if (MSG_SUCCESS != ret) { + LoggerE("Failed to get platform message structure: %d", ret); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get platform Message structure"); + } else { + // Send message + message->setMessageStatus(MessageStatus::STATUS_SENDING); + req = msg_create_struct(MSG_STRUCT_REQUEST_INFO); + msg_set_struct_handle(req, MSG_REQUEST_MESSAGE_HND, platform_msg); + + int req_id = -1; + ret = msg_get_int_value(req, MSG_REQUEST_REQUESTID_INT, &req_id); + if (MSG_SUCCESS != ret) { + LoggerE("Failed to get send request ID: %d", ret); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get send request ID"); + } else { if (MessageType::MMS == message->getType()) { - LoggerD("Send MMS message"); - ret = msg_mms_send_message(m_msg_handle, req); + LoggerD("Send MMS message"); + ret = msg_mms_send_message(m_msg_handle, req); } else if (MessageType::SMS == message->getType()) { - LoggerD("Send SMS message"); - ret = msg_sms_send_message(m_msg_handle, req); + LoggerD("Send SMS message"); + ret = msg_sms_send_message(m_msg_handle, req); } else { - LoggerE("Invalid message type: %d", message->getType()); - throw common::TypeMismatchException("Invalid message type"); + LoggerE("Invalid message type: %d", message->getType()); + platform_result = PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Invalid message type"); } - if (ret != MSG_SUCCESS) { + if (platform_result) { + if (ret != MSG_SUCCESS) { LoggerE("Failed to send message: %d", ret); - throw common::UnknownException("Failed to send message"); - } - - ret = msg_get_int_value(req, MSG_REQUEST_REQUESTID_INT, &req_id); - if (ret != MSG_SUCCESS) { - LoggerE("Failed to get message request ID: %d", ret); - throw common::UnknownException("Failed to get send request"); - } - LoggerD("req_id: %d", req_id); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to send message"); + } else { + ret = msg_get_int_value(req, MSG_REQUEST_REQUESTID_INT, &req_id); + if (ret != MSG_SUCCESS) { + LoggerE("Failed to get message request ID: %d", ret); + platform_result = PlatformResult(ErrorCode::UNKNOWN_ERR, "Failed to get send request"); + } + if (platform_result.IsSuccess()) { + LoggerD("req_id: %d", req_id); - msgInfo = Message::convertPlatformShortMessageToObject(platform_msg); + platform_result = Message::convertPlatformShortMessageToObject(platform_msg, &msgInfo); + if (platform_result.IsSuccess()) { - int conversationId; - ret = msg_get_conversation(m_msg_handle, msg_id, msg_conv); - if (MSG_SUCCESS != ret) { - LoggerE("Failed to get conv"); - } - msg_get_int_value(msg_conv, MSG_CONV_MSG_THREAD_ID_INT, - &conversationId); - message->setConversationId(conversationId); + int conversationId; + ret = msg_get_conversation(m_msg_handle, msg_id, msg_conv); + if (MSG_SUCCESS != ret) { + LoggerE("Failed to get conv"); + } + msg_get_int_value(msg_conv, MSG_CONV_MSG_THREAD_ID_INT, + &conversationId); + message->setConversationId(conversationId); - int folderId = msgInfo->getFolderId(); - message->setFolderId(folderId); + int folderId = msgInfo->getFolderId(); + message->setFolderId(folderId); - time_t timestamp = msgInfo->getTimestamp(); - message->setTimeStamp(timestamp); + time_t timestamp = msgInfo->getTimestamp(); + message->setTimeStamp(timestamp); - std::string from = msgInfo->getFrom(); - LoggerD("From:%s", from.c_str()); - message->setFrom(from); + std::string from = msgInfo->getFrom(); + LoggerD("From:%s", from.c_str()); + message->setFrom(from); - bool isRead = msgInfo->getIsRead(); - message->setIsRead(isRead); + bool isRead = msgInfo->getIsRead(); + message->setIsRead(isRead); - int inResponseTo = msgInfo->getInResponseTo(); - message->setInResponseTo(inResponseTo); + int inResponseTo = msgInfo->getInResponseTo(); + message->setInResponseTo(inResponseTo); - m_sendRequests[req_id] = callback; - LoggerD("Send MSG_SUCCESS"); - } - catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - if (!g_idle_add(sendMessageCompleteCB, static_cast(callback))) { - LoggerE("g_idle addition failed"); - delete callback; - callback = NULL; - } - } - catch (...) { - LoggerE("Message send failed"); - common::UnknownException e("Message send failed"); - callback->setError(e.name(), e.message()); - if (!g_idle_add(sendMessageCompleteCB, static_cast(callback))) { - LoggerE("g_idle addition failed"); - delete callback; - callback = NULL; + m_sendRequests[req_id] = callback; + LoggerD("Send MSG_SUCCESS"); + } + } + } } + } } + } + + if (msg_release_struct(&req) != MSG_SUCCESS) { + LoggerW("Request structure is already destroyed"); + } + if (msg_release_struct(&platform_msg) != MSG_SUCCESS) { + LoggerW("Platform message is already destroyed"); + } + if (msg_release_struct(&send_opt) != MSG_SUCCESS) { + LoggerW("Platform message is already destroyed"); + } + if (msg_release_struct(&msg_conv) != MSG_SUCCESS) { + LoggerW("Platform message is already destroyed"); + } + + delete msgInfo; + + return platform_result; +} - if (msg_release_struct(&req) != MSG_SUCCESS) { - LoggerW("Request structure is already destroyed"); - } - if (msg_release_struct(&platform_msg) != MSG_SUCCESS) { - LoggerW("Platform message is already destroyed"); - } - if (msg_release_struct(&send_opt) != MSG_SUCCESS) { - LoggerW("Platform message is already destroyed"); - } - if (msg_release_struct(&msg_conv) != MSG_SUCCESS) { - LoggerW("Platform message is already destroyed"); - } - delete msgInfo; +PlatformResult ShortMsgManager::sendMessage(MessageRecipientsCallbackData* callback) +{ + LoggerD("Entered"); - return; + if (!callback){ + LoggerE("Callback is null"); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Callback is null"); + } + + PlatformResult platform_result(ErrorCode::NO_ERROR); + + platform_result = SendMessagePlatform(callback); + + if (!platform_result) { + LoggerE("Message send failed"); + + callback->setError(platform_result); + + if (!g_idle_add(sendMessageCompleteCB, static_cast(callback))) { + LoggerE("g_idle addition failed"); + delete callback; + callback = NULL; + } + } + return platform_result; } void ShortMsgManager::sendStatusCallback(msg_struct_t sent_status) @@ -418,7 +416,7 @@ static void sent_status_cb(msg_handle_t handle, return; } -void ShortMsgManager::callProperEventMessages(EventMessages* event, +PlatformResult ShortMsgManager::callProperEventMessages(EventMessages* event, msg_storage_change_type_t storageChangeType) { LoggerD("Entered event.items.size()=%d event.removed_conversations.size()=%d" @@ -432,8 +430,14 @@ void ShortMsgManager::callProperEventMessages(EventMessages* event, if(MSG_STORAGE_CHANGE_DELETE == storageChangeType) { eventConv->items = event->removed_conversations; } else { - eventConv->items = ShortMsgManager::getConversationsForMessages( - event->items, storageChangeType); + PlatformResult ret = ShortMsgManager::getConversationsForMessages( + event->items, storageChangeType, &(eventConv->items)); + if (ret.IsError()) { + LoggerD("Error while getting conversations for message"); + delete event; + delete eventConv; + return ret; + } } switch (storageChangeType) { @@ -498,6 +502,7 @@ void ShortMsgManager::callProperEventMessages(EventMessages* event, } delete event; delete eventConv; + return PlatformResult(ErrorCode::NO_ERROR); } void ShortMsgManager::storage_change_cb(msg_handle_t handle, @@ -529,156 +534,160 @@ void ShortMsgManager::storage_change_cb(msg_handle_t handle, */ EventMessages* eventSMS = NULL; EventMessages* eventMMS = NULL; - try { - // if allocation below fails than exception is thrown - no NULL check - eventSMS = new EventMessages(); - eventSMS->service_type = MessageType::SMS; - eventSMS->service_id = SMS_ACCOUNT_ID; - eventMMS = new EventMessages(); - eventMMS->service_type = MessageType::MMS; - eventMMS->service_id = MMS_ACCOUNT_ID; - - if (MSG_STORAGE_CHANGE_DELETE == storageChangeType) { - - ShortMsgManager& msg_manager = ShortMsgManager::getInstance(); - std::lock_guard lock(msg_manager.m_mutex); - - std::map* rem_msgs[2] = { // Recently removed messages - &msg_manager.m_sms_removed_messages, - &msg_manager.m_mms_removed_messages }; - std::map* rem_convs[2] = { // Recently removed conversations - &msg_manager.m_sms_removed_msg_id_conv_id_map, - &msg_manager.m_mms_removed_msg_id_conv_id_map }; - EventMessages* dest_event[2] = { // SMS/MMS EventMessage to be propagated - eventSMS, - eventMMS }; - std::map* conv_map[2] = { //Map conversationId - object - &msg_manager.m_sms_removed_conv_id_object_map, - &msg_manager.m_mms_removed_conv_id_object_map }; - - for(int event_i = 0; event_i < 2; ++event_i) { - - std::map& cur_rem_msgs = *(rem_msgs[event_i]); - std::map& cur_rem_convs = *(rem_convs[event_i]); - EventMessages* cur_dest_event = dest_event[event_i]; - std::map& cur_conv_map = *(conv_map[event_i]); - std::unordered_set conv_rem_now; - - for (int i = 0; i < pMsgIdList->nCount; ++i) { - const msg_message_id_t& msg_id = pMsgIdList->msgIdList[i]; - LoggerD("pMsgIdList[%d] = %d", i, msg_id); - - std::map ::iterator it = cur_rem_msgs.find(msg_id); - if(it != cur_rem_msgs.end()) { - LoggerD("[%d] is %s, Pushing message with id:%d subject:%s", i, - (0 == i) ? "SMS" : "MMS", - it->second->getId(), - it->second->getSubject().c_str()); - cur_dest_event->items.push_back(it->second); - cur_rem_msgs.erase(it); - } - std::map::iterator cit = cur_rem_convs.find(msg_id); - if(cit != cur_rem_convs.end()) { - conv_rem_now.insert(cit->second); - cur_rem_convs.erase(cit); - } + // if allocation below fails than exception is thrown - no NULL check + eventSMS = new EventMessages(); + eventSMS->service_type = MessageType::SMS; + eventSMS->service_id = SMS_ACCOUNT_ID; + eventMMS = new EventMessages(); + eventMMS->service_type = MessageType::MMS; + eventMMS->service_id = MMS_ACCOUNT_ID; + + if (MSG_STORAGE_CHANGE_DELETE == storageChangeType) { + + ShortMsgManager& msg_manager = ShortMsgManager::getInstance(); + std::lock_guard lock(msg_manager.m_mutex); + + std::map* rem_msgs[2] = { // Recently removed messages + &msg_manager.m_sms_removed_messages, + &msg_manager.m_mms_removed_messages }; + std::map* rem_convs[2] = { // Recently removed conversations + &msg_manager.m_sms_removed_msg_id_conv_id_map, + &msg_manager.m_mms_removed_msg_id_conv_id_map }; + EventMessages* dest_event[2] = { // SMS/MMS EventMessage to be propagated + eventSMS, + eventMMS }; + std::map* conv_map[2] = { //Map conversationId - object + &msg_manager.m_sms_removed_conv_id_object_map, + &msg_manager.m_mms_removed_conv_id_object_map }; + + for(int event_i = 0; event_i < 2; ++event_i) { + + std::map& cur_rem_msgs = *(rem_msgs[event_i]); + std::map& cur_rem_convs = *(rem_convs[event_i]); + EventMessages* cur_dest_event = dest_event[event_i]; + std::map& cur_conv_map = *(conv_map[event_i]); + std::unordered_set conv_rem_now; + + for (int i = 0; i < pMsgIdList->nCount; ++i) { + const msg_message_id_t& msg_id = pMsgIdList->msgIdList[i]; + LoggerD("pMsgIdList[%d] = %d", i, msg_id); + + std::map ::iterator it = cur_rem_msgs.find(msg_id); + if(it != cur_rem_msgs.end()) { + LoggerD("[%d] is %s, Pushing message with id:%d subject:%s", i, + (0 == i) ? "SMS" : "MMS", + it->second->getId(), + it->second->getSubject().c_str()); + cur_dest_event->items.push_back(it->second); + cur_rem_msgs.erase(it); } - for (auto it = conv_rem_now.begin(); it != conv_rem_now.end(); it++) { - const int cur_rem_conv_id = *it; - - //--------------------------------------------------------------------- - // Check if we have removed last message from conversation - // - bool found = false; - for(auto it2 = cur_rem_convs.begin(); - it2 != cur_rem_convs.end(); - it2++) { - if( cur_rem_conv_id == it2->second) { - found = true; - break; - } + std::map::iterator cit = cur_rem_convs.find(msg_id); + if(cit != cur_rem_convs.end()) { + conv_rem_now.insert(cit->second); + cur_rem_convs.erase(cit); + } + } + + for (auto it = conv_rem_now.begin(); it != conv_rem_now.end(); it++) { + const int cur_rem_conv_id = *it; + + //--------------------------------------------------------------------- + // Check if we have removed last message from conversation + // + bool found = false; + for(auto it2 = cur_rem_convs.begin(); + it2 != cur_rem_convs.end(); + it2++) { + if( cur_rem_conv_id == it2->second) { + found = true; + break; } + } - if(false == found) { - //We have removed last message from conversation + if(false == found) { + //We have removed last message from conversation - std::map::iterator conv_it = - cur_conv_map.find(cur_rem_conv_id); - if(conv_it != cur_conv_map.end()) { - LoggerD("Pushing removed %s MessageConversation(%p) with id:%d", - (0 == event_i) ? "SMS" : "MMS", - conv_it->second.get(), cur_rem_conv_id); + std::map::iterator conv_it = + cur_conv_map.find(cur_rem_conv_id); + if(conv_it != cur_conv_map.end()) { + LoggerD("Pushing removed %s MessageConversation(%p) with id:%d", + (0 == event_i) ? "SMS" : "MMS", + conv_it->second.get(), cur_rem_conv_id); - cur_dest_event->removed_conversations.push_back( - conv_it->second); - cur_conv_map.erase(conv_it); - } else { - LoggerW("Couldn't find ConversationPtr object with id:%d", - cur_rem_conv_id); - } + cur_dest_event->removed_conversations.push_back( + conv_it->second); + cur_conv_map.erase(conv_it); + } else { + LoggerW("Couldn't find ConversationPtr object with id:%d", + cur_rem_conv_id); } } } + } - } else { - for (int i = 0; i < pMsgIdList->nCount; ++i) { - - msg_struct_t msg = ShortMsgManager::getInstance().getMessage( - pMsgIdList->msgIdList[i]); - if (NULL == msg) { - LoggerE("Failed to load short message"); + } else { + PlatformResult ret(ErrorCode::NO_ERROR); + for (int i = 0; i < pMsgIdList->nCount; ++i) { + + msg_struct_t msg; + ret = ShortMsgManager::getInstance().getMessage(pMsgIdList->msgIdList[i], &msg); + if (ret.IsError() || NULL == msg) { + LoggerE("Failed to load short message"); + delete eventSMS; + eventSMS = NULL; + delete eventMMS; + eventMMS = NULL; + return; + } + std::shared_ptr message; + Message* message_ptr = nullptr; + ret = Message::convertPlatformShortMessageToObject(msg, &message_ptr); + if (ret.IsError()) { + LoggerE("Failed to load short message"); + msg_release_struct(&msg); + delete eventSMS; + eventSMS = NULL; + delete eventMMS; + eventMMS = NULL; + return; + } + message.reset(message_ptr); + msg_release_struct(&msg); + switch (message->getType()) { + case MessageType::SMS: + eventSMS->items.push_back(message); + break; + case MessageType::MMS: + eventMMS->items.push_back(message); + break; + default: + LoggerE("Unsupported message type"); delete eventSMS; eventSMS = NULL; delete eventMMS; eventMMS = NULL; - throw common::UnknownException("Failed to load short message"); - } - std::shared_ptr message( - Message::convertPlatformShortMessageToObject(msg)); - msg_release_struct(&msg); - switch (message->getType()) { - case MessageType::SMS: - eventSMS->items.push_back(message); - break; - case MessageType::MMS: - eventMMS->items.push_back(message); - break; - default: - LoggerE("Unsupported message type"); - delete eventSMS; - eventSMS = NULL; - delete eventMMS; - eventMMS = NULL; - throw common::UnknownException("Unsupported message type"); - } + return; } } + } - if (!eventSMS->items.empty() || !eventSMS->removed_conversations.empty()) { - ShortMsgManager::callProperEventMessages(eventSMS, storageChangeType); - } else { - LoggerD("No SMS messages, not triggering eventSMS"); - delete eventSMS; - eventSMS = NULL; - } - if (!eventMMS->items.empty() || !eventMMS->removed_conversations.empty()) { - ShortMsgManager::callProperEventMessages(eventMMS, storageChangeType); - } else { - LoggerD("No MMS messages, not triggering eventMMS"); - delete eventMMS; - eventMMS = NULL; - } - - } catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - delete eventSMS; - delete eventMMS; - } catch (...) { - LoggerE("Failed to call callback"); + if (!eventSMS->items.empty() || !eventSMS->removed_conversations.empty()) { + PlatformResult ret = ShortMsgManager::callProperEventMessages(eventSMS, storageChangeType); + //PlatformResult could be ignored here. eventSMS is deleted in callProperEventMessages() + } else { + LoggerD("No SMS messages, not triggering eventSMS"); delete eventSMS; + eventSMS = NULL; + } + if (!eventMMS->items.empty() || !eventMMS->removed_conversations.empty()) { + PlatformResult ret = ShortMsgManager::callProperEventMessages(eventMMS, storageChangeType); + //PlatformResult could be ignored here. eventMMS is deleted in callProperEventMessages() + } else { + LoggerD("No MMS messages, not triggering eventMMS"); delete eventMMS; + eventMMS = NULL; } } @@ -704,19 +713,15 @@ void ShortMsgManager::addDraftMessage(MessageCallbackUserData* callback) LoggerE("Callback is null"); return; } - try { - std::lock_guard lock(m_mutex); - std::shared_ptr message = callback->getMessage(); - - addDraftMessagePlatform(message); - - } catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Message add draft failed"); - common::UnknownException e("Message add draft failed"); - callback->setError(e.name(), e.message()); + { + std::lock_guard lock(m_mutex); + std::shared_ptr message = callback->getMessage(); + + PlatformResult ret = addDraftMessagePlatform(message); + if (ret.IsError()) { + LoggerE("%d (%s)", ret.error_code(), ret.message().c_str()); + callback->setError(ret); + } } // Complete task @@ -737,70 +742,62 @@ void ShortMsgManager::removeMessages(MessagesCallbackUserData* callback) } int error; - try { + std::vector> messages; + + { std::lock_guard lock(m_mutex); - std::vector> messages = callback->getMessages(); + messages = callback->getMessages(); MessageType type = callback->getMessageServiceType(); for(auto it = messages.begin() ; it != messages.end(); ++it) { if((*it)->getType() != type) { LoggerE("Invalid message type: %d", (*it)->getType()); - throw common::TypeMismatchException("Error while deleting message"); + callback->SetError(PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Error while deleting message")); + break; } } - for (auto it = messages.begin() ; it != messages.end(); ++it) { - const int id = (*it)->getId(); + if (!callback->isError()) { + for (auto it = messages.begin() ; it != messages.end(); ++it) { + const int id = (*it)->getId(); - //Store message object - LoggerD("Storing removed message (id:%d) in m_removed_messages", id); - switch((*it)->getType()) { + //Store message object + LoggerD("Storing removed message (id:%d) in m_removed_messages", id); + switch((*it)->getType()) { - case SMS: m_sms_removed_messages[id] = (*it); break; - case MMS: m_mms_removed_messages[id] = (*it); break; - default: - LoggerD("Unknown message type: %d", (*it)->getType()); - break; - } + case SMS: m_sms_removed_messages[id] = (*it); break; + case MMS: m_mms_removed_messages[id] = (*it); break; + default: + LoggerD("Unknown message type: %d", (*it)->getType()); + break; + } - error = msg_delete_message(m_msg_handle, id); - if (MSG_SUCCESS != error) { - LoggerE("Error while deleting message"); - throw common::UnknownException("Error while deleting message"); + error = msg_delete_message(m_msg_handle, id); + if (MSG_SUCCESS != error) { + LoggerE("Error while deleting message"); + callback->SetError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while deleting message")); + break; + } } } - } catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Messages remove failed"); - common::UnknownException e("Messages remove failed"); - callback->setError(e.name(), e.message()); } - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); - - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const common::PlatformException& err) { - LoggerE("Error while calling removeShortMsg callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Unknown error when calling removeShortMsg callback."); + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve( + callback->getJson()->get().at(JSON_CALLBACK_ID).get(), + callback->getJson()->serialize() + ); + } else { + LoggerD("Calling success callback"); + + auto json = callback->getJson(); + picojson::object& obj = json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); } delete callback; @@ -817,102 +814,102 @@ void ShortMsgManager::updateMessages(MessagesCallbackUserData* callback) } LoggerD("messages to update: %d", callback->getMessages().size()); - try { + + { std::lock_guard lock(m_mutex); std::vector> messages = callback->getMessages(); MessageType type = callback->getMessageServiceType(); for (auto it = messages.begin() ; it != messages.end(); ++it) { if ((*it)->getType() != type) { LoggerE("Invalid message type"); - throw common::TypeMismatchException("Error while updating message"); + callback->SetError(PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, "Error while updating message")); + break; } } - for (auto it = messages.begin() ; it != messages.end(); ++it) { - - LoggerD("updating Message(%p) msg_id:%d", (*it).get(), (*it)->getId()); - - msg_struct_t platform_msg - = Message::convertPlatformShortMessageToStruct(it->get(), m_msg_handle); - if (NULL == platform_msg) { - LoggerE("Failed to prepare platform message"); - throw common::UnknownException("Cannot prepare platform message"); - } - msg_struct_t sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT); - int error = msg_update_message(m_msg_handle, platform_msg, sendOpt); - msg_release_struct(&platform_msg); - msg_release_struct(&sendOpt); - if (error != MSG_SUCCESS) { - LoggerE("Failed to update message %d", (*it)->getId()); - throw common::UnknownException("Error while updating message"); + if (!callback->isError()) { + for (auto it = messages.begin() ; it != messages.end(); ++it) { + LoggerD("updating Message(%p) msg_id:%d", (*it).get(), (*it)->getId()); + + msg_struct_t platform_msg = nullptr; + PlatformResult ret = Message::convertPlatformShortMessageToStruct(it->get(), m_msg_handle, &platform_msg); + if (ret.IsError()) { + LoggerE("%s", ret.message().c_str()); + callback->SetError(ret); + break; + } + if (NULL == platform_msg) { + LoggerE("Failed to prepare platform message"); + callback->SetError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot prepare platform message")); + break; + } + msg_struct_t sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT); + int error = msg_update_message(m_msg_handle, platform_msg, sendOpt); + msg_release_struct(&platform_msg); + msg_release_struct(&sendOpt); + if (error != MSG_SUCCESS) { + LoggerE("Failed to update message %d", (*it)->getId()); + callback->SetError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while updating message")); + break; + } } } - } catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Messages update failed"); - common::UnknownException e("Messages update failed"); - callback->setError(e.name(), e.message()); } - try { - if (callback->isError()) { - LoggerD("Calling error callback"); + if (callback->isError()) { + LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); + PostQueue::getInstance().resolve( + callback->getJson()->get().at(JSON_CALLBACK_ID).get(), + callback->getJson()->serialize() + ); + } else { + LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); + auto json = callback->getJson(); + picojson::object& obj = json->get(); - auto messages = callback->getMessages(); - picojson::array array; - auto each = [&array] (std::shared_ptr m)->void { - array.push_back(MessagingUtil::messageToJson(m)); - }; + auto messages = callback->getMessages(); + picojson::array array; + auto each = [&array] (std::shared_ptr m)->void { + array.push_back(MessagingUtil::messageToJson(m)); + }; - for_each(messages.begin(), messages.end(), each); + for_each(messages.begin(), messages.end(), each); - obj[JSON_DATA] = picojson::value(array); + obj[JSON_DATA] = picojson::value(array); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const common::PlatformException& err) { - LoggerE("Error while calling updateShortMsg callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Unknown error when calling updateShortMsg callback."); + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); } delete callback; callback = NULL; } -msg_struct_t ShortMsgManager::getMessage(int msg_id) +PlatformResult ShortMsgManager::getMessage(int msg_id, msg_struct_t* out_msg) { msg_struct_t sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT); msg_struct_t msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); + int error = msg_get_message(m_msg_handle, msg_id, msg, sendOpt); if (MSG_SUCCESS != error) { LoggerE("Couldn't retrieve message from service, msgId: %d, error:%d", msg_id, error); - throw common::UnknownException("Couldn't retrieve message from service"); + msg_release_struct(&sendOpt); + msg_release_struct(&msg); + return PlatformResult(ErrorCode::UNKNOWN_ERR, "Couldn't retrieve message from service"); } msg_release_struct(&sendOpt); - return msg; + *out_msg = msg; + return PlatformResult(ErrorCode::NO_ERROR); } -ConversationPtrVector ShortMsgManager::getConversationsForMessages( +PlatformResult ShortMsgManager::getConversationsForMessages( MessagePtrVector messages, - msg_storage_change_type_t storageChangeType) + msg_storage_change_type_t storageChangeType, ConversationPtrVector* result) { LoggerD("Entered messages.size()=%d storageChangeType=%d", messages.size(), storageChangeType); @@ -930,14 +927,16 @@ ConversationPtrVector ShortMsgManager::getConversationsForMessages( if (0 == count) { //conversation isn't loaded yet unique_conv_ids.insert(conv_id); - ConversationPtr conv = MessageConversation::convertMsgConversationToObject( - conv_id, ShortMsgManager::getInstance().m_msg_handle); - + ConversationPtr conv; + PlatformResult ret = MessageConversation::convertMsgConversationToObject( + conv_id, ShortMsgManager::getInstance().m_msg_handle, &conv); + if (ret.IsError()) return ret; LoggerD("Pushed conv=%p", conv.get()); convs.push_back(conv); } } - return convs; + *result = convs; + return PlatformResult(ErrorCode::NO_ERROR); } void ShortMsgManager::findMessages(FindMsgCallbackUserData* callback) @@ -949,83 +948,78 @@ void ShortMsgManager::findMessages(FindMsgCallbackUserData* callback) return; } - try { + { std::lock_guard lock(m_mutex); - std::vector messagesIds = - MessagingDatabaseManager::getInstance().findShortMessages(callback); - int msgListCount = messagesIds.size(); - LoggerD("Found %d messages", msgListCount); - - msg_struct_t msg; - msg_struct_t sendOpt; - msg_error_t err; - for (int i = 0; i < msgListCount; i++) { - msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); - sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT); - err = msg_get_message(m_msg_handle, messagesIds.at(i), msg, sendOpt); - - if (MSG_SUCCESS != err) { - LoggerE("Failed to get platform message structure: %d", err); - throw common::UnknownException("Cannot get platform Message structure"); - } + std::vector messagesIds; + PlatformResult ret = MessagingDatabaseManager::getInstance().findShortMessages(callback, &messagesIds); + if (ret.IsError()) { + LoggerE("Failed to find short message: %s (%d)", ret.message().c_str(), ret.error_code()); + callback->SetError(ret); + } - try { - std::shared_ptr message( - Message::convertPlatformShortMessageToObject(msg)); - callback->addMessage(message); + if (!callback->isError()) { + int msgListCount = messagesIds.size(); + LoggerD("Found %d messages", msgListCount); + + msg_struct_t msg; + msg_struct_t sendOpt; + msg_error_t err; + for (int i = 0; i < msgListCount; i++) { + msg = msg_create_struct(MSG_STRUCT_MESSAGE_INFO); + sendOpt = msg_create_struct(MSG_STRUCT_SENDOPT); + err = msg_get_message(m_msg_handle, messagesIds.at(i), msg, sendOpt); + + if (MSG_SUCCESS != err) { + LoggerE("Failed to get platform message structure: %d", err); + callback->SetError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get platform Message structure")); + break; + } - LoggerD("Created message with id %d:", messagesIds[i]); - } - catch(const common::InvalidValuesException& exception) { - //Ignore messages with not supported/unrecognized type + std::shared_ptr message; + Message* message_ptr = nullptr; + PlatformResult ret = Message::convertPlatformShortMessageToObject(msg, &message_ptr); + if (ret.IsError() && ret.error_code() != ErrorCode::INVALID_VALUES_ERR) { + LoggerE("Cannot get platform Message structure"); + callback->SetError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Cannot get platform Message structure")); + break; + } + if (!callback->isError()) { + message.reset(message_ptr); + callback->addMessage(message); + LoggerD("Created message with id %d:", messagesIds[i]); + msg_release_struct(&sendOpt); + msg_release_struct(&msg); + } } - - msg_release_struct(&sendOpt); - msg_release_struct(&msg); } - - } catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Message add draft failed"); - common::UnknownException e("Message add draft failed"); - callback->setError(e.name(), e.message()); } - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback with %d messages:", - callback->getMessages().size()); - - auto json = callback->getJson(); - picojson::object& obj = json->get(); - - std::vector response; - auto messages = callback->getMessages(); - std::for_each(messages.begin(), messages.end(), [&response](MessagePtr &message){ - response.push_back(MessagingUtil::messageToJson(message)); - }); - - obj[JSON_DATA] = picojson::value(response); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const common::PlatformException& err) { - LoggerE("Error while calling findMessages callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Failed to call findMessages callback."); + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve( + callback->getJson()->get().at(JSON_CALLBACK_ID).get(), + callback->getJson()->serialize() + ); + } else { + LoggerD("Calling success callback with %d messages:", + callback->getMessages().size()); + + auto json = callback->getJson(); + picojson::object& obj = json->get(); + + std::vector response; + auto messages = callback->getMessages(); + std::for_each(messages.begin(), messages.end(), [&response](MessagePtr &message){ + response.push_back(MessagingUtil::messageToJson(message)); + }); + + obj[JSON_DATA] = picojson::value(response); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); } delete callback; @@ -1041,61 +1035,58 @@ void ShortMsgManager::findConversations(ConversationCallbackData* callback) return; } - try { + { std::lock_guard lock(m_mutex); - std::vector conversationsIds = - MessagingDatabaseManager::getInstance().findShortMessageConversations(callback); - int convListCount = conversationsIds.size(); - LoggerD("Found %d conversations", convListCount); - - for (int i = 0; i < convListCount; i++) { - std::shared_ptr conversation = - MessageConversation::convertMsgConversationToObject( - conversationsIds.at(i), m_msg_handle); + std::vector conversationsIds; + PlatformResult ret = MessagingDatabaseManager::getInstance(). + findShortMessageConversations(callback, &conversationsIds); + if (ret.IsError()) { + LoggerE("Cannot get platform Message structure"); + callback->SetError(ret); + } - callback->addConversation(conversation); + if (!callback->isError()) { + int convListCount = conversationsIds.size(); + LoggerD("Found %d conversations", convListCount); + + for (int i = 0; i < convListCount; i++) { + std::shared_ptr conversation; + PlatformResult ret = MessageConversation::convertMsgConversationToObject( + conversationsIds.at(i), m_msg_handle, &conversation); + if (ret.IsSuccess()) { + callback->addConversation(conversation); + } else { + callback->SetError(ret); + } + } } - } catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Message add draft failed"); - common::UnknownException e("Message add draft failed"); - callback->setError(e.name(), e.message()); } - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); - auto json = callback->getJson(); - picojson::object& obj = json->get(); - - std::vector response; - auto conversations = callback->getConversations(); - std::for_each(conversations.begin(), conversations.end(), - [&response](std::shared_ptr &conversation) { - response.push_back(MessagingUtil::conversationToJson(conversation)); - } - ); - obj[JSON_DATA] = picojson::value(response); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const common::PlatformException& err) { - LoggerE("Error while calling findConversations callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Failed to call findConversations callback."); + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve( + callback->getJson()->get().at(JSON_CALLBACK_ID).get(), + callback->getJson()->serialize() + ); + } else { + LoggerD("Calling success callback"); + auto json = callback->getJson(); + picojson::object& obj = json->get(); + + std::vector response; + auto conversations = callback->getConversations(); + std::for_each(conversations.begin(), conversations.end(), + [&response](std::shared_ptr &conversation) { + response.push_back(MessagingUtil::conversationToJson(conversation)); + } + ); + obj[JSON_DATA] = picojson::value(response); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); } delete callback; @@ -1114,122 +1105,119 @@ void ShortMsgManager::removeConversations(ConversationCallbackData* callback) int error = MSG_SUCCESS; msg_handle_t handle = NULL; - try { + { std::lock_guard lock(m_mutex); ConversationPtrVector conversations = callback->getConversations(); const MessageType type = callback->getMessageServiceType(); + std::map* msg_id_conv_id_map = NULL; + std::map* conv_id_object_map = NULL; + error = msg_open_msg_handle(&handle); if (MSG_SUCCESS != error) { LoggerE("Open message handle error: %d", error); - throw common::UnknownException("Error while creatng message handle"); + callback->SetError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Error while creatng message handle")); } - for(auto it = conversations.begin() ; it != conversations.end(); ++it) { - if((*it)->getType() != type) { - LoggerE("Invalid message type"); - throw common::TypeMismatchException("Error while deleting message conversation"); - } + if (!callback->isError()) { + for(auto it = conversations.begin() ; it != conversations.end(); ++it) { + if((*it)->getType() != type) { + LoggerE("Invalid message type"); + callback->SetError(PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, + "Error while deleting message conversation")); + break; + } + } } - std::map* msg_id_conv_id_map = NULL; - std::map* conv_id_object_map = NULL; - if(MessageType::SMS == type) { - msg_id_conv_id_map = &m_sms_removed_msg_id_conv_id_map; - conv_id_object_map = &m_sms_removed_conv_id_object_map; - } else if(MessageType::MMS == type) { - msg_id_conv_id_map = &m_mms_removed_msg_id_conv_id_map; - conv_id_object_map = &m_mms_removed_conv_id_object_map; - } else { - LoggerE("Invalid message type:%d for ShortMsgManager!", type); - throw common::UnknownException("Invalid message type for ShortMsgManager!"); + if (!callback->isError()) { + if(MessageType::SMS == type) { + msg_id_conv_id_map = &m_sms_removed_msg_id_conv_id_map; + conv_id_object_map = &m_sms_removed_conv_id_object_map; + } else if(MessageType::MMS == type) { + msg_id_conv_id_map = &m_mms_removed_msg_id_conv_id_map; + conv_id_object_map = &m_mms_removed_conv_id_object_map; + } else { + LoggerE("Invalid message type:%d for ShortMsgManager!", type); + callback->SetError(PlatformResult(ErrorCode::UNKNOWN_ERR, "Invalid message type for ShortMsgManager!")); + } } - int conv_index = 0; - for (auto it = conversations.begin() ; it != conversations.end(); - ++it, ++conv_index) { - - ConversationPtr conv = (*it); - msg_thread_id_t conv_id = conv->getConversationId(); - - LoggerD("[%d] MessageConversation(%p) conv_id:%d", conv_index, conv.get(), - conv_id); - - msg_struct_list_s conv_view_list; - error = msg_get_conversation_view_list(handle, (msg_thread_id_t)conv_id, - &conv_view_list); - if (MSG_SUCCESS == error) { - for(int msg_index = 0; msg_index < conv_view_list.nCount; ++msg_index) - { - int cur_msg_id = 0; - error = msg_get_int_value(conv_view_list.msg_struct_info[msg_index], - MSG_CONV_MSG_ID_INT, &cur_msg_id); - - if(MSG_SUCCESS == error && cur_msg_id > 0) { - (*msg_id_conv_id_map)[cur_msg_id] = conv_id; - (*conv_id_object_map)[conv_id] = conv; - - LoggerD("[%d] message[%d] msg_id:%d," - "saved MessageConversation(%p) with conv_id:%d", - conv_index, msg_index, cur_msg_id, conv.get(), conv_id); - } else { - LoggerE("[%d] Couldn't get msg_id, error: %d!", error); + if (!callback->isError()) { + int conv_index = 0; + for (auto it = conversations.begin() ; it != conversations.end(); + ++it, ++conv_index) { + + ConversationPtr conv = (*it); + msg_thread_id_t conv_id = conv->getConversationId(); + + LoggerD("[%d] MessageConversation(%p) conv_id:%d", conv_index, conv.get(), + conv_id); + + msg_struct_list_s conv_view_list; + error = msg_get_conversation_view_list(handle, (msg_thread_id_t)conv_id, + &conv_view_list); + if (MSG_SUCCESS == error) { + for(int msg_index = 0; msg_index < conv_view_list.nCount; ++msg_index) + { + int cur_msg_id = 0; + error = msg_get_int_value(conv_view_list.msg_struct_info[msg_index], + MSG_CONV_MSG_ID_INT, &cur_msg_id); + + if(MSG_SUCCESS == error && cur_msg_id > 0) { + (*msg_id_conv_id_map)[cur_msg_id] = conv_id; + (*conv_id_object_map)[conv_id] = conv; + + LoggerD("[%d] message[%d] msg_id:%d," + "saved MessageConversation(%p) with conv_id:%d", + conv_index, msg_index, cur_msg_id, conv.get(), conv_id); + } else { + LoggerE("[%d] Couldn't get msg_id, error: %d!", error); + } } + } else { + LoggerE("[%d] Couldn' get conversation view list for conv_id:%d error: %d", + conv_index, conv_id, error); } - } else { - LoggerE("[%d] Couldn' get conversation view list for conv_id:%d error: %d", - conv_index, conv_id, error); - } - msg_release_list_struct(&conv_view_list); + msg_release_list_struct(&conv_view_list); - error = msg_delete_thread_message_list(handle, (msg_thread_id_t) conv_id, - FALSE); - if (MSG_SUCCESS != error) { - LoggerE("Error while deleting message conversation"); - throw common::UnknownException("Error while deleting message conversation"); + error = msg_delete_thread_message_list(handle, (msg_thread_id_t) conv_id, + FALSE); + if (MSG_SUCCESS != error) { + LoggerE("Error while deleting message conversation"); + callback->SetError(PlatformResult(ErrorCode::UNKNOWN_ERR, + "Error while deleting message conversation")); + break; + } } - } - - } catch (const common::PlatformException& err) { - LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); - callback->setError(err.name(), err.message()); - } catch (...) { - LoggerE("Messages remove failed"); - common::UnknownException e("Messages remove failed"); - callback->setError(e.name(), e.message()); } - error = msg_close_msg_handle(&handle); - if (MSG_SUCCESS != error) { - LoggerW("Cannot close message handle: %d", error); + if (!callback->isError()) { + error = msg_close_msg_handle(&handle); + if (MSG_SUCCESS != error) { + LoggerW("Cannot close message handle: %d", error); + } } - try { - if (callback->isError()) { - LoggerD("Calling error callback"); - PostQueue::getInstance().resolve( - callback->getJson()->get().at(JSON_CALLBACK_ID).get(), - callback->getJson()->serialize() - ); - } else { - LoggerD("Calling success callback"); - - auto json = callback->getJson(); - picojson::object& obj = json->get(); - obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); - - PostQueue::getInstance().resolve( - obj.at(JSON_CALLBACK_ID).get(), - json->serialize() - ); - } - } catch (const common::PlatformException& err) { - LoggerE("Error while calling removeConversations callback: %s (%s)", - (err.name()).c_str(), (err.message()).c_str()); - } catch (...) { - LoggerE("Unknown error when calling removeConversations callback."); + if (callback->isError()) { + LoggerD("Calling error callback"); + PostQueue::getInstance().resolve( + callback->getJson()->get().at(JSON_CALLBACK_ID).get(), + callback->getJson()->serialize() + ); + } else { + LoggerD("Calling success callback"); + + auto json = callback->getJson(); + picojson::object& obj = json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); + + PostQueue::getInstance().resolve( + obj.at(JSON_CALLBACK_ID).get(), + json->serialize() + ); } delete callback; @@ -1258,6 +1246,5 @@ ShortMsgManager::~ShortMsgManager() m_mms_removed_conv_id_object_map.size()); } - } // messaging } // extension diff --git a/src/messaging/short_message_manager.h b/src/messaging/short_message_manager.h index 78d3b828..5626e999 100644 --- a/src/messaging/short_message_manager.h +++ b/src/messaging/short_message_manager.h @@ -14,6 +14,7 @@ //#include +#include "common/platform_result.h" #include "change_listener_container.h" #include "messaging_util.h" #include "message_service.h" @@ -29,7 +30,7 @@ class ShortMsgManager { public: static ShortMsgManager& getInstance(); - void sendMessage(MessageRecipientsCallbackData* callback); + common::PlatformResult sendMessage(MessageRecipientsCallbackData* callback); void sendStatusCallback(msg_struct_t sent_status); void addDraftMessage(MessageCallbackUserData* callback); @@ -41,7 +42,7 @@ public: void removeMessages(MessagesCallbackUserData* callback); void updateMessages(MessagesCallbackUserData* callback); - msg_struct_t getMessage(int msg_id); + common::PlatformResult getMessage(int msg_id, msg_struct_t* out_msg); private: ShortMsgManager(); ShortMsgManager(const ShortMsgManager &); @@ -60,7 +61,8 @@ private: msg_id_list_s *pMsgIdList, void* data); - void addDraftMessagePlatform(std::shared_ptr message); + common::PlatformResult addDraftMessagePlatform(std::shared_ptr message); + common::PlatformResult SendMessagePlatform(MessageRecipientsCallbackData* callback); /** * Returns unique list of conversations for given vector of messages. * storageChangeType is needed to filter conversations returned: @@ -71,10 +73,10 @@ private: * @param storageChangeType * @return */ - static ConversationPtrVector getConversationsForMessages( + static common::PlatformResult getConversationsForMessages( MessagePtrVector messages, - msg_storage_change_type_t storageChangeType); - static void callProperEventMessages(EventMessages* event, + msg_storage_change_type_t storageChangeType, ConversationPtrVector* result); + static common::PlatformResult callProperEventMessages(EventMessages* event, msg_storage_change_type_t storageChangeType); typedef std::map SendReqMap; SendReqMap m_sendRequests;