From e9fc7290bd1f4613f83ec47b8f5001814a20c0b9 Mon Sep 17 00:00:00 2001 From: Maciek Blim Date: Mon, 22 Dec 2014 13:38:13 +0100 Subject: [PATCH] [Messaging] addMessagesListener - messageremoved (for emails) Change-Id: I3ffeb42f3e996258df6a69ecfb49eea13460e205 Signed-off-by: Maciek Blim --- src/messaging/change_listener_container.cc | 52 +++-- src/messaging/change_listener_container.h | 2 +- src/messaging/message_storage.cc | 5 +- src/messaging/message_storage.h | 4 +- src/messaging/messages_callback_user_data.cc | 12 ++ src/messaging/messages_callback_user_data.h | 1 + src/messaging/messages_change_callback.cc | 189 +++++++++---------- src/messaging/messages_change_callback.h | 22 +-- src/messaging/messaging_api.js | 30 +-- src/messaging/messaging_instance.cc | 20 +- 10 files changed, 186 insertions(+), 151 deletions(-) diff --git a/src/messaging/change_listener_container.cc b/src/messaging/change_listener_container.cc index a191190c..5278df1e 100644 --- a/src/messaging/change_listener_container.cc +++ b/src/messaging/change_listener_container.cc @@ -27,33 +27,31 @@ ChangeListenerContainer::ChangeListenerContainer(): } // --- Listeners registration functions --- -/* - *long ChangeListenerContainer::addMessageChangeListener( - * std::shared_ptr callback) - *{ - * LoggerD("Entered"); - * // Check type of service for which listener should be registered - * // and lock appropriate mutex - * MessageType mtype = callback->getServiceType(); - * if (MessageType(SMS) == mtype || MessageType(MMS) == mtype) - * { - * std::lock_guard lock(m_short_lock); - * int new_id = getNextId(); - * m_short_message_callbacks.insert(std::make_pair(new_id, callback)); - * LoggerD("Added callback for ShortMessage, watchId: %d", new_id); - * return new_id; - * } - * else if (MessageType(EMAIL) == mtype) { - * std::lock_guard lock(m_email_lock); - * int new_id = getNextId(); - * m_email_message_callbacks.insert(std::make_pair(new_id, callback)); - * LoggerD("Added callback for Email, watchId: %d", new_id); - * return new_id; - * } - * LoggerE("Listener with invalid MessageService type - failed to register"); - * return -1; - *} - */ +long ChangeListenerContainer::addMessageChangeListener( + std::shared_ptr callback) +{ + LoggerD("Entered"); + // Check type of service for which listener should be registered + // and lock appropriate mutex + MessageType mtype = callback->getServiceType(); + if (MessageType(SMS) == mtype || MessageType(MMS) == mtype) + { + //std::lock_guard lock(m_short_lock); + //int new_id = getNextId(); + //m_short_message_callbacks.insert(std::make_pair(new_id, callback)); + //LoggerD("Added callback for ShortMessage, watchId: %d", new_id); + //return new_id; + } + else if (MessageType(EMAIL) == mtype) { + std::lock_guard lock(m_email_lock); + int new_id = getNextId(); + m_email_message_callbacks.insert(std::make_pair(new_id, callback)); + LoggerD("Added callback for Email, watchId: %d", new_id); + return new_id; + } + LoggerE("Listener with invalid MessageService type - failed to register"); + return -1; +} /* *long ChangeListenerContainer::addConversationChangeListener( diff --git a/src/messaging/change_listener_container.h b/src/messaging/change_listener_container.h index ffbe9432..0fe650e4 100644 --- a/src/messaging/change_listener_container.h +++ b/src/messaging/change_listener_container.h @@ -85,7 +85,7 @@ class ChangeListenerContainer { // Interface for listener's manipulation (registration and removal). - //long addMessageChangeListener(std::shared_ptr callback); + long addMessageChangeListener(std::shared_ptr callback); //long addConversationChangeListener(std::shared_ptr callback); //long addFolderChangeListener(std::shared_ptr callback); void removeChangeListener(long id); diff --git a/src/messaging/message_storage.cc b/src/messaging/message_storage.cc index f8151758..26de147b 100644 --- a/src/messaging/message_storage.cc +++ b/src/messaging/message_storage.cc @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "message_storage.h" +#include "messages_change_callback.h" +#include "change_listener_container.h" #include "common/logger.h" @@ -32,9 +34,10 @@ MessageType MessageStorage::getMsgServiceType() const return m_msg_type; } -long MessageStorage::addMessagesChangeListener() +long MessageStorage::addMessagesChangeListener(std::shared_ptr callback) { LoggerD("Entered"); + return ChangeListenerContainer::getInstance().addMessageChangeListener(callback); } long MessageStorage::addConversationsChangeListener() diff --git a/src/messaging/message_storage.h b/src/messaging/message_storage.h index 39be9438..42fce1d8 100644 --- a/src/messaging/message_storage.h +++ b/src/messaging/message_storage.h @@ -16,6 +16,8 @@ namespace extension { namespace messaging { +class MessagesChangeCallback; + class MessageStorage; typedef std::shared_ptr MessageStoragePtr; @@ -37,7 +39,7 @@ public: // Listeners registration/removal is common for all types of storage // and does not have to be overwritten in derived classes. - long addMessagesChangeListener(); + long addMessagesChangeListener(std::shared_ptr callback); long addConversationsChangeListener(); long addFoldersChangeListener(); void removeChangeListener(); diff --git a/src/messaging/messages_callback_user_data.cc b/src/messaging/messages_callback_user_data.cc index ba7ea039..b45c7955 100644 --- a/src/messaging/messages_callback_user_data.cc +++ b/src/messaging/messages_callback_user_data.cc @@ -15,6 +15,18 @@ MessagesCallbackUserData::MessagesCallbackUserData(): { } +MessagesCallbackUserData::MessagesCallbackUserData(long cid, bool keep): + common::CallbackUserData(), + m_is_error(false), + m_service_type(MessageType::UNDEFINED) +{ + auto json = std::shared_ptr(new picojson::value(picojson::object())); + picojson::object& o = json->get(); + o[JSON_CALLBACK_ID] = picojson::value(static_cast(cid)); + o[JSON_CALLBACK_KEEP] = picojson::value(keep); + setJson(json); +} + MessagesCallbackUserData::~MessagesCallbackUserData() { } diff --git a/src/messaging/messages_callback_user_data.h b/src/messaging/messages_callback_user_data.h index 208a16ee..4d330dc5 100644 --- a/src/messaging/messages_callback_user_data.h +++ b/src/messaging/messages_callback_user_data.h @@ -19,6 +19,7 @@ class Message; class MessagesCallbackUserData: public common::CallbackUserData { public: MessagesCallbackUserData(); + MessagesCallbackUserData(long cid, bool keep = false); virtual ~MessagesCallbackUserData(); void addMessage(std::shared_ptr msg); diff --git a/src/messaging/messages_change_callback.cc b/src/messaging/messages_change_callback.cc index 2631320a..5307e409 100644 --- a/src/messaging/messages_change_callback.cc +++ b/src/messaging/messages_change_callback.cc @@ -7,6 +7,7 @@ #include "common/logger.h" #include "common/platform_exception.h" +#include "messaging_instance.h" #include "messages_change_callback.h" //#include "JSMessage.h" @@ -34,80 +35,72 @@ const char* MESSAGESADDED = "messagesadded"; const char* MESSAGESUPDATED = "messagesupdated"; const char* MESSAGESREMOVED = "messagesremoved"; -MessagesChangeCallback::MessagesChangeCallback(/*JSContextRef global_ctx, - JSObjectRef on_added_obj, - JSObjectRef on_updated_obj, - JSObjectRef on_removed_obj,*/ +MessagesChangeCallback::MessagesChangeCallback( + long cid, int service_id, MessageType service_type) : - /*m_callback_data(global_ctx),*/ + m_callback_data(cid, true), m_service_id(service_id), m_msg_type(service_type), m_is_act(true) { - LOGD("Entered"); - - //m_callback_data.setCallback(MESSAGESADDED, on_added_obj); - //m_callback_data.setCallback(MESSAGESUPDATED, on_updated_obj); - //m_callback_data.setCallback(MESSAGESREMOVED, on_removed_obj); + LoggerD("Entered"); } MessagesChangeCallback::~MessagesChangeCallback() { - LOGD("Entered"); + LoggerD("Entered"); } -/* - *MessagePtrVector MessagesChangeCallback::filterMessages( - * AbstractFilterPtr filter, - * const MessagePtrVector& source_messages, - * const int service_id) - *{ - * LOGD("Entered sourceMessages.size():%d filter:%s", source_messages.size(), - * (filter ? "PRESENT" : "NULL")); - * - * if (filter) { - * MessagePtrVector filtered_messages; - * MessagePtrVector::const_iterator it = source_messages.begin(); - * MessagePtrVector::const_iterator end_it = source_messages.end(); - * - * for(int i = 0; it != end_it ; ++i, ++it) { - * const MessagePtr& message = *it; - * message->setServiceId(service_id); - * - * const bool matched = filter->isMatching(message.get()); - * if(matched) { - * filtered_messages.push_back(message); - * } - * - * LOGD("[%d] is Message(%p) {", i, message.get()); - * LOGD("[%d] messageId: %d", i, message->getId()); - * LOGD("[%d] message subject: %s", i, message->getSubject().c_str()); - * LOGD("[%d] from: %s", i, message->getFrom().c_str()); - * - * if(message->getBody()) { - * const std::string& pBody = message->getBody()->getPlainBody(); - * LOGD("[%d] message plainBody: %s", i, limitedString(pBody).c_str()); - * } - * - * LOGD("[%d] matched filter: %s", i, matched ? "YES" : "NO"); - * LOGD("[%d] }"); - * } - * - * LOGD("returning matching %d of %d messages", filtered_messages.size(), - * source_messages.size()); - * return filtered_messages; - * } - * else { - * return source_messages; - * } - *} - */ +MessagePtrVector MessagesChangeCallback::filterMessages( + tizen::AbstractFilterPtr filter, + const MessagePtrVector& source_messages, + const int service_id) +{ + LoggerD("Entered sourceMessages.size():%d filter:%s", source_messages.size(), + (filter ? "PRESENT" : "NULL")); + + if (filter) { + MessagePtrVector filtered_messages; + MessagePtrVector::const_iterator it = source_messages.begin(); + MessagePtrVector::const_iterator end_it = source_messages.end(); + + for(int i = 0; it != end_it ; ++i, ++it) { + const MessagePtr& message = *it; + message->setServiceId(service_id); + + const bool matched = filter->isMatching(message.get()); + if(matched) { + filtered_messages.push_back(message); + } + + LoggerD("[%d] is Message(%p) {", i, message.get()); + LoggerD("[%d] messageId: %d", i, message->getId()); + LoggerD("[%d] message subject: %s", i, message->getSubject().c_str()); + LoggerD("[%d] from: %s", i, message->getFrom().c_str()); + + if(message->getBody()) { + const std::string& pBody = message->getBody()->getPlainBody(); + LoggerD("[%d] message plainBody: %s", i, limitedString(pBody).c_str()); + } + + LoggerD("[%d] matched filter: %s", i, matched ? "YES" : "NO"); + LoggerD("[%d] }"); + } + + LoggerD("returning matching %d of %d messages", filtered_messages.size(), + source_messages.size()); + return filtered_messages; + } + else { + return source_messages; + } +} /* *void MessagesChangeCallback::added(const MessagePtrVector& msgs) *{ - * LOGD("Entered num messages: %d", msgs.size()); + * LoggerD("Entered num messages: %d", msgs.size()); * if (!m_is_act) { * return; * } @@ -117,20 +110,20 @@ MessagesChangeCallback::~MessagesChangeCallback() * //cancel callback only if filter did remove all messages * //if callback was called with empty msgs list, call it * if (msgs.size() > 0 && filtered_msgs.size() == 0) { - * LOGD("All messages were filtered out, not calling callback"); + * LoggerD("All messages were filtered out, not calling callback"); * return; * } * JSObjectRef js_obj = JSMessage::messageVectorToJSObjectArray( * ctx, filtered_msgs); * - * LOGD("Calling:%s with:%d added messages", MESSAGESADDED, + * LoggerD("Calling:%s with:%d added messages", MESSAGESADDED, * filtered_msgs.size()); * m_callback_data.invokeCallback(MESSAGESADDED, js_obj); *} * *void MessagesChangeCallback::updated(const MessagePtrVector& msgs) *{ - * LOGD("Entered num messages: %d", msgs.size()); + * LoggerD("Entered num messages: %d", msgs.size()); * if (!m_is_act) { * return; * } @@ -140,13 +133,13 @@ MessagesChangeCallback::~MessagesChangeCallback() * //cancel callback only if filter did remove all messages * //if callback was called with empty msgs list, call it * if (msgs.size() > 0 && filtered_msgs.size() == 0) { - * LOGD("All messages were filtered out, not calling callback"); + * LoggerD("All messages were filtered out, not calling callback"); * return; * } * JSObjectRef js_obj = JSMessage::messageVectorToJSObjectArray( * ctx, filtered_msgs); * - * LOGD("Calling:%s with:%d updated messages", MESSAGESUPDATED, + * LoggerD("Calling:%s with:%d updated messages", MESSAGESUPDATED, * filtered_msgs.size()); * m_callback_data.invokeCallback(MESSAGESUPDATED, js_obj); *} @@ -154,41 +147,47 @@ MessagesChangeCallback::~MessagesChangeCallback() void MessagesChangeCallback::removed(const MessagePtrVector& msgs) { -/* - * LOGD("Enter event: msgs.size() = %d", msgs.size()); - * if (!m_is_act) { - * return; - * } - * - * MessagePtrVector filtered_msgs = filterMessages(m_filter, msgs, m_service_id); - * //cancel callback only if filter did remove all messages - * //if callback was called with empty msgs list, call it - * if (msgs.size() > 0 && filtered_msgs.size() == 0) { - * LOGD("All messages were filtered out, not calling callback"); - * return; - * } - * JSObjectRef js_obj = JSMessage::messageVectorToJSObjectArray( - * ctx, filtered_msgs); - * - * LOGD("Calling:%s with:%d removed messages", MESSAGESREMOVED, - * filtered_msgs.size()); - * m_callback_data.invokeCallback(MESSAGESREMOVED, js_obj); - */ + LoggerD("Enter event: msgs.size() = %d", msgs.size()); + if (!m_is_act) { + return; + } + + MessagePtrVector filtered_msgs = filterMessages(m_filter, msgs, m_service_id); + //cancel callback only if filter did remove all messages + //if callback was called with empty msgs list, call it + if (msgs.size() > 0 && filtered_msgs.size() == 0) { + LoggerD("All messages were filtered out, not calling callback"); + return; + } + + picojson::array array; + auto each = [&array] (std::shared_ptr m)->void { + array.push_back(MessagingUtil::messageToJson(m)); + }; + + for_each(filtered_msgs.begin(), filtered_msgs.end(), each); + + LoggerD("Calling:%s with:%d removed messages", MESSAGESREMOVED, + filtered_msgs.size()); + + 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); + MessagingInstance::getInstance().PostMessage(json->serialize().c_str()); + } -/* - *void MessagesChangeCallback::setFilter(AbstractFilterPtr filter) - *{ - * m_filter = filter; - *} - */ +void MessagesChangeCallback::setFilter(tizen::AbstractFilterPtr filter) +{ + m_filter = filter; +} -/* - *AbstractFilterPtr MessagesChangeCallback::getFilter() const - *{ - * return m_filter; - *} - */ +AbstractFilterPtr MessagesChangeCallback::getFilter() const +{ + return m_filter; +} int MessagesChangeCallback::getServiceId() const { diff --git a/src/messaging/messages_change_callback.h b/src/messaging/messages_change_callback.h index f4d44c30..772c1fda 100644 --- a/src/messaging/messages_change_callback.h +++ b/src/messaging/messages_change_callback.h @@ -9,10 +9,11 @@ //#include -//#include +#include "MsgCommon/AbstractFilter.h" #include "message.h" #include "messaging_util.h" +#include "messages_callback_user_data.h" namespace extension { namespace messaging { @@ -24,6 +25,7 @@ extern const char* MESSAGESREMOVED; class MessagesChangeCallback { public: MessagesChangeCallback( + long cid, int service_id, MessageType service_type); virtual ~MessagesChangeCallback(); @@ -32,17 +34,15 @@ public: //void updated(const MessagePtrVector& messages); void removed(const MessagePtrVector& messages); - //void setFilter(DeviceAPI::Tizen::AbstractFilterPtr filter); - //DeviceAPI::Tizen::AbstractFilterPtr getFilter() const; + void setFilter(tizen::AbstractFilterPtr filter); + tizen::AbstractFilterPtr getFilter() const; int getServiceId() const; MessageType getServiceType() const; - /* - *static MessagePtrVector filterMessages( - * DeviceAPI::Tizen::AbstractFilterPtr a_filter, - * const MessagePtrVector& a_sourceMessages, - * const int service_id); - */ + static MessagePtrVector filterMessages( + tizen::AbstractFilterPtr a_filter, + const MessagePtrVector& a_sourceMessages, + const int service_id); void setActive(bool act); bool isActive(); @@ -50,8 +50,8 @@ public: void setItems(MessagePtrVector& items); MessagePtrVector getItems(); private: - //Common::MultiCallbackUserData m_callback_data; - //DeviceAPI::Tizen::AbstractFilterPtr m_filter; + MessagesCallbackUserData m_callback_data; + tizen::AbstractFilterPtr m_filter; int m_service_id; MessageType m_msg_type; bool m_is_act; diff --git a/src/messaging/messaging_api.js b/src/messaging/messaging_api.js index 731a6579..db7ade8e 100644 --- a/src/messaging/messaging_api.js +++ b/src/messaging/messaging_api.js @@ -981,23 +981,14 @@ MessageStorage.prototype.addMessagesChangeListener = function () { optional: true, nullable: true} ]); - var listeners = []; - if (args.messagesChangeCallback.messagesadded) listeners.push('messagesadded'); - if (args.messagesChangeCallback.messagesupdated) listeners.push('messagesupdated'); - if (args.messagesChangeCallback.messagesremoved) listeners.push('messagesremoved'); + var self = this; - bridge({ - cmd: 'MessageStorage_addMessagesChangeListener', - args: { - filter: args.filter, - listeners: listeners - } - }).then({ + var cid = bridge.listener({ messagesadded: function (data) { if (args.messagesChangeCallback.messagesadded) { var messages = []; data.forEach(function (el) { - messages.push(new tizen.Message(el)); + messages.push(new tizen.Message(el.type, new MessageInit_(el))); }); args.messagesChangeCallback.messagesadded.call(null, messages); } @@ -1006,7 +997,7 @@ MessageStorage.prototype.addMessagesChangeListener = function () { if (args.messagesChangeCallback.messagesupdated) { var messages = []; data.forEach(function (el) { - messages.push(new tizen.Message(el)); + messages.push(new tizen.Message(el.type, new MessageInit_(el))); }); args.messagesChangeCallback.messagesupdated.call(null, messages); } @@ -1015,12 +1006,23 @@ MessageStorage.prototype.addMessagesChangeListener = function () { if (args.messagesChangeCallback.messagesremoved) { var messages = []; data.forEach(function (el) { - messages.push(new tizen.Message(el)); + messages.push(new tizen.Message(el.type, new MessageInit_(el))); }); args.messagesChangeCallback.messagesremoved.call(null, messages); } } }); + + var result = bridge.sync({ + cmd: 'MessageStorage_addMessagesChangeListener', + cid: cid, + args: { + filter: args.filter || null, + serviceId: self.service.id + } + }); + + return result; }; MessageStorage.prototype. addConversationsChangeListener = function () { diff --git a/src/messaging/messaging_instance.cc b/src/messaging/messaging_instance.cc index 927b2948..92508237 100644 --- a/src/messaging/messaging_instance.cc +++ b/src/messaging/messaging_instance.cc @@ -9,6 +9,8 @@ #include "common/logger.h" +#include "MsgCommon/AbstractFilter.h" +#include "messages_change_callback.h" #include "messaging_manager.h" #include "messaging_util.h" #include "message_storage.h" @@ -118,7 +120,6 @@ MessagingInstance::MessagingInstance() REGISTER_ASYNC(FUN_MESSAGE_STORAGE_FIND_CONVERSATIONS, MessageStorageFindConversations); REGISTER_ASYNC(FUN_MESSAGE_STORAGE_REMOVE_CONVERSATIONS, MessageStorageRemoveConversations); REGISTER_ASYNC(FUN_MESSAGE_STORAGE_FIND_FOLDERS, MessageStorageFindFolders); - REGISTER_ASYNC(FUN_MESSAGE_STORAGE_ADD_MESSAGES_CHANGE_LISTENER, MessageStorageAddMessagesChangeListener); REGISTER_ASYNC(FUN_MESSAGE_STORAGE_ADD_CONVERSATIONS_CHANGE_LISTENER, MessageStorageAddConversationsChangeListener); REGISTER_ASYNC(FUN_MESSAGE_STORAGE_ADD_FOLDER_CHANGE_LISTENER, MessageStorageAddFolderChangeListener); #undef REGISTER_ASYNC @@ -126,6 +127,7 @@ MessagingInstance::MessagingInstance() RegisterSyncHandler(c, std::bind(&MessagingInstance::x, this, _1, _2)); REGISTER_SYNC(FUN_MESSAGE_SERVICE_SYNC, MessageServiceSync); REGISTER_SYNC(FUN_MESSAGE_SERVICE_STOP_SYNC, MessageServiceStopSync); + REGISTER_SYNC(FUN_MESSAGE_STORAGE_ADD_MESSAGES_CHANGE_LISTENER, MessageStorageAddMessagesChangeListener); REGISTER_SYNC(FUN_MESSAGE_STORAGE_REMOVE_CHANGE_LISTENER, MessageStorageRemoveChangeListener); #undef REGISTER_SYNC } @@ -403,6 +405,22 @@ void MessagingInstance::MessageStorageAddMessagesChangeListener(const picojson:: picojson::object& out) { LoggerD("Entered"); + picojson::object data = args.get(JSON_DATA).get(); + const long callbackId = static_cast(args.get(JSON_CALLBACK_ID).get()); + + int serviceId = static_cast(data.at(FUNCTIONS_HIDDEN_ARGS_SERVICE_ID).get()); + auto service = MessagingManager::getInstance().getMessageServiceEmail(serviceId); + + std::shared_ptr callback(new MessagesChangeCallback( + callbackId, serviceId, service->getMsgServiceType())); + + // TODO filter + // callback->setFilter(tizen::AbstractFilterPtr(new tizen::AbstractFilter())); + + long op_id = service->getMsgStorage()->addMessagesChangeListener(callback); + + picojson::value v(static_cast(op_id)); + ReportSuccess(v, out); } void MessagingInstance::MessageStorageAddConversationsChangeListener(const picojson::value& args, -- 2.34.1