[Messaging] conversations change listener
authorMaciek Blim <m.blim@samsung.com>
Wed, 7 Jan 2015 10:07:14 +0000 (11:07 +0100)
committerMaciek Blim <m.blim@samsung.com>
Wed, 7 Jan 2015 10:49:25 +0000 (11:49 +0100)
Change-Id: I53c8ac80e7935402cd6d58bdd6bd1083fa8f4fd4
Signed-off-by: Maciek Blim <m.blim@samsung.com>
13 files changed:
src/messaging/DBus/MessageProxy.cpp
src/messaging/change_listener_container.cc
src/messaging/change_listener_container.h
src/messaging/conversation_callback_data.cc
src/messaging/conversation_callback_data.h
src/messaging/conversations_change_callback.cc [new file with mode: 0644]
src/messaging/conversations_change_callback.h [new file with mode: 0644]
src/messaging/message_conversation.cc
src/messaging/message_storage.cc
src/messaging/message_storage.h
src/messaging/messaging.gyp
src/messaging/messaging_api.js
src/messaging/messaging_instance.cc

index 893881d..4f40cc5 100644 (file)
@@ -24,7 +24,7 @@
 #include "../message.h"
 #include "../message_email.h"
 
-//#include <MessageConversation.h>
+#include "../message_conversation.h"
 //#include <MessageFolder.h>
 
 #include "../change_listener_container.h"
@@ -134,32 +134,31 @@ void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id,
         throw common::UnknownException("Failed to load email");
     }
     std::shared_ptr<Message> msg = Message::convertPlatformEmailToObject(*mail_data);
-//    TODO uncomment when conversations will be available
-//    ConversationPtr conv = MessageConversation::convertEmailConversationToObject(
-//            thread_id);
+    ConversationPtr conv = MessageConversation::convertEmailConversationToObject(
+            thread_id);
 
     EventMessages* eventMsg = new EventMessages();
     eventMsg->service_type = MessageType::EMAIL;
     eventMsg->service_id = account_id;
     eventMsg->items.push_back(msg);
-//    EventConversations* eventConv = new EventConversations();
-//    eventConv->service_type = MessageType::EMAIL;
-//    eventConv->service_id = account_id;
-//    eventConv->items.push_back(conv);
+    EventConversations* eventConv = new EventConversations();
+    eventConv->service_type = MessageType::EMAIL;
+    eventConv->service_id = account_id;
+    eventConv->items.push_back(conv);
     switch (event) {
         case NOTI_MAIL_ADD:
             ChangeListenerContainer::getInstance().callMessageAdded(eventMsg);
-//            if (conv->getMessageCount() == 1) { TODO
-//                LoggerD("This thread is new, triggering conversationAdded");
-//                ChangeListenerContainer::getInstance().callConversationAdded(eventConv);
-//            } else {
-//                LoggerD("This thread is not new, but it's updated");
-//                ChangeListenerContainer::getInstance().callConversationUpdated(eventConv);
-//            }
+            if (conv->getMessageCount() == 1) {
+                LoggerD("This thread is new, triggering conversationAdded");
+                ChangeListenerContainer::getInstance().callConversationAdded(eventConv);
+            } else {
+                LoggerD("This thread is not new, but it's updated");
+                ChangeListenerContainer::getInstance().callConversationUpdated(eventConv);
+            }
             break;
         case NOTI_MAIL_UPDATE:
             ChangeListenerContainer::getInstance().callMessageUpdated(eventMsg);
-//            ChangeListenerContainer::getInstance().callConversationUpdated(eventConv);
+            ChangeListenerContainer::getInstance().callConversationUpdated(eventConv);
             break;
         default:
             LoggerW("Unknown event type: %d", event);
@@ -167,7 +166,7 @@ void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id,
 
     }
     delete eventMsg;
-//    delete eventConv;
+    delete eventConv;
 
     EmailManager::getInstance().freeMessage(mail_data);
 }
@@ -229,18 +228,18 @@ void MessageProxy::notifyEmailManager(const std::string& idsString,
 void MessageProxy::handleThreadRemoveEvent(int account_id, int thread_id)
 {
     LoggerD("Enter");
-/*    //event is called after thread is removed, so we just set thread id
   ConversationPtr conv = std::make_shared<MessageConversation>();
   conv->setConversationId(thread_id);
- *
- *    EventConversations* eventConv = new EventConversations();
*    eventConv->service_type = MessageType::EMAIL;
*    eventConv->service_id = account_id;
*    eventConv->items.push_back(conv);
*    ChangeListenerContainer::getInstance().callConversationRemoved(eventConv);
*    delete eventConv;
*    eventConv = NULL;
- */
+    //event is called after thread is removed, so we just set thread id and type
+    ConversationPtr conv = std::make_shared<MessageConversation>();
+    conv->setConversationId(thread_id);
+    conv->setType(MessageType::EMAIL);
+
   EventConversations* eventConv = new EventConversations();
   eventConv->service_type = MessageType::EMAIL;
   eventConv->service_id = account_id;
   eventConv->items.push_back(conv);
   ChangeListenerContainer::getInstance().callConversationRemoved(eventConv);
   delete eventConv;
+    eventConv = NULL;
 }
 
 void MessageProxy::handleMailboxEvent(int account_id, int mailbox_id, int event)
index 8590711..7e4dd56 100644 (file)
@@ -53,33 +53,31 @@ long ChangeListenerContainer::addMessageChangeListener(
     return -1;
 }
 
-/*
- *long ChangeListenerContainer::addConversationChangeListener(
- *        std::shared_ptr<ConversationsChangeCallback> 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<std::mutex> lock(m_short_lock);
- *        int new_id = getNextId();
- *        m_short_conversation_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<std::mutex> lock(m_email_lock);
- *        int new_id = getNextId();
- *        m_email_conversation_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(
+        std::shared_ptr<ConversationsChangeCallback> 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<std::mutex> lock(m_short_lock);
+        //int new_id = getNextId();
+        //m_short_conversation_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<std::mutex> lock(m_email_lock);
+        int new_id = getNextId();
+        m_email_conversation_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::addFolderChangeListener(
@@ -123,34 +121,30 @@ void ChangeListenerContainer::removeChangeListener(long id)
         LoggerE("Invalid id %d given.", id);
         return;
     }
-    /*
-     *if (removeCallbackIfExists<MessagesChangeCallback>(
-     *        context, m_short_message_callbacks,id)) {
-     *    LoggerD("ShortMessage message listener with id: %d removed", id);
-     *}
-     *else if (removeCallbackIfExists<ConversationsChangeCallback>(
-     *        context, m_short_conversation_callbacks, id)) {
-     *    LoggerD("ShortMessage conversation listener with id: %d removed", id);
-     *}
-     *else if (removeCallbackIfExists<FoldersChangeCallback>(
-     *        context, m_short_folder_callbacks, id)) {
-     *    LoggerD("ShortMessage folder listener with id: %d removed", id);
-     *}
-     */
+    //if (removeCallbackIfExists<MessagesChangeCallback>(
+            //context, m_short_message_callbacks,id)) {
+        //LoggerD("ShortMessage message listener with id: %d removed", id);
+    //}
+    //else if (removeCallbackIfExists<ConversationsChangeCallback>(
+            //context, m_short_conversation_callbacks, id)) {
+        //LoggerD("ShortMessage conversation listener with id: %d removed", id);
+    //}
+    //else if (removeCallbackIfExists<FoldersChangeCallback>(
+            //context, m_short_folder_callbacks, id)) {
+        //LoggerD("ShortMessage folder listener with id: %d removed", id);
+    //}
     /*else*/ if (removeCallbackIfExists<MessagesChangeCallback>(
             m_email_message_callbacks, id)) {
         LoggerD("Email message listener with id: %d removed", id);
     }
-    /*
-     *else if (removeCallbackIfExists<ConversationsChangeCallback>(
-     *        context, m_email_conversation_callbacks, id)) {
-     *    LoggerD("Email conversation listener with id: %d removed", id);
-     *}
-     *else if (removeCallbackIfExists<FoldersChangeCallback>(
-     *        context, m_email_folder_callbacks,id)) {
-     *    LoggerD("Email folder listener with id: %d removed", id);
-     *}
-     */
+    else if (removeCallbackIfExists<ConversationsChangeCallback>(
+            m_email_conversation_callbacks, id)) {
+        LoggerD("Email conversation listener with id: %d removed", id);
+    }
+    //else if (removeCallbackIfExists<FoldersChangeCallback>(
+            //context, m_email_folder_callbacks,id)) {
+        //LoggerD("Email folder listener with id: %d removed", id);
+    //}
     else {
         LoggerW("WatchId %d not found", id);
     }
@@ -251,107 +245,101 @@ void ChangeListenerContainer::callMessageRemoved(EventMessages* event)
 }
 
 // -- for conversation --
-/*
- *void ChangeListenerContainer::callConversationAdded(EventConversations* event)
- *{
- *    LoggerD("Entered");
- *
- *    if(MessageType(SMS) == event->service_type ||
- *            MessageType(MMS) == event->service_type) {
- *        LoggerD("Calling converationadded for ShortMessage");
- *        CCLmap callbacksCopy;
- *        {
- *            std::lock_guard<std::mutex> shortlock(m_short_lock);
- *            callbacksCopy = m_short_conversation_callbacks;
- *        }
- *        callAdded<ConversationsChangeCallback, EventConversations>(
- *                callbacksCopy, event);
- *    }
- *    else if(MessageType(EMAIL) == event->service_type) {
- *        LoggerD("Calling conversationadded for Email");
- *        CCLmap callbacksCopy;
- *        {
- *            std::lock_guard<std::mutex> maillock(m_email_lock);
- *            callbacksCopy = m_email_conversation_callbacks;
- *        }
- *        callAdded<ConversationsChangeCallback, EventConversations>(
- *                callbacksCopy, event);
- *    }
- *    else {
- *        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
- *    }
- *}
- */
+void ChangeListenerContainer::callConversationAdded(EventConversations* event)
+{
+    LoggerD("Entered");
 
-/*
- *void ChangeListenerContainer::callConversationUpdated(EventConversations* event)
- *{
- *    LoggerD("Entered");
- *
- *    if(MessageType(SMS) == event->service_type ||
- *            MessageType(MMS) == event->service_type) {
- *        LoggerD("Calling conversationupdated for ShortConversation");
- *        CCLmap callbacksCopy;
- *        {
- *            std::lock_guard<std::mutex> shortlock(m_short_lock);
- *            callbacksCopy = m_short_conversation_callbacks;
- *        }
- *        callUpdated<ConversationsChangeCallback, EventConversations>(
- *                callbacksCopy, event);
- *    }
- *    else if(MessageType(EMAIL) == event->service_type) {
- *        LoggerD("Calling conversationupdated for Email");
- *        CCLmap callbacksCopy;
- *        {
- *            std::lock_guard<std::mutex> maillock(m_email_lock);
- *            callbacksCopy = m_email_conversation_callbacks;
- *        }
- *        callUpdated<ConversationsChangeCallback, EventConversations>(
- *                callbacksCopy, event);
- *    }
- *    else {
- *        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
- *    }
- *}
- */
+    if(MessageType(SMS) == event->service_type ||
+            MessageType(MMS) == event->service_type) {
+        //LoggerD("Calling converationadded for ShortMessage");
+        //CCLmap callbacksCopy;
+        //{
+            //std::lock_guard<std::mutex> shortlock(m_short_lock);
+            //callbacksCopy = m_short_conversation_callbacks;
+        //}
+        //callAdded<ConversationsChangeCallback, EventConversations>(
+                //callbacksCopy, event);
+    }
+    else if(MessageType(EMAIL) == event->service_type) {
+        LoggerD("Calling conversationadded for Email");
+        CCLmap callbacksCopy;
+        {
+            std::lock_guard<std::mutex> maillock(m_email_lock);
+            callbacksCopy = m_email_conversation_callbacks;
+        }
+        callAdded<ConversationsChangeCallback, EventConversations>(
+                callbacksCopy, event);
+    }
+    else {
+        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+    }
+}
 
-/*
- *void ChangeListenerContainer::callConversationRemoved(EventConversations* event)
- *{
- *    LoggerD("Entered");
- *
- *    if(MessageType(SMS) == event->service_type ||
- *            MessageType(MMS) == event->service_type) {
- *        LoggerD("Calling conversationremoved for ShortConversation");
- *        CCLmap callbacksCopy;
- *        {
- *            std::lock_guard<std::mutex> shortlock(m_short_lock);
- *            LoggerD("m_short_conversation_callbacks.size() = %d",
- *                    m_short_conversation_callbacks.size());
- *
- *            callbacksCopy = m_short_conversation_callbacks;
- *        }
- *        callRemoved<ConversationsChangeCallback, EventConversations>(
- *                callbacksCopy, event);
- *    }
- *    else if(MessageType(EMAIL) == event->service_type) {
- *        LoggerD("Calling conversationremoved for Email");
- *        CCLmap callbacksCopy;
- *        {
- *            std::lock_guard<std::mutex> maillock(m_email_lock);
- *            LoggerD("m_email_conversation_callbacks.size() = %d",
- *                m_email_conversation_callbacks.size());
- *
- *            callbacksCopy = m_email_conversation_callbacks;
- *        }
- *        callRemoved<ConversationsChangeCallback, EventConversations>(
- *                callbacksCopy, event);
- *    }
- *    else {
- *        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
- *    }
- *}
- */
+void ChangeListenerContainer::callConversationUpdated(EventConversations* event)
+{
+    LoggerD("Entered");
+
+    if(MessageType(SMS) == event->service_type ||
+            MessageType(MMS) == event->service_type) {
+        //LoggerD("Calling conversationupdated for ShortConversation");
+        //CCLmap callbacksCopy;
+        //{
+            //std::lock_guard<std::mutex> shortlock(m_short_lock);
+            //callbacksCopy = m_short_conversation_callbacks;
+        //}
+        //callUpdated<ConversationsChangeCallback, EventConversations>(
+                //callbacksCopy, event);
+    }
+    else if(MessageType(EMAIL) == event->service_type) {
+        LoggerD("Calling conversationupdated for Email");
+        CCLmap callbacksCopy;
+        {
+            std::lock_guard<std::mutex> maillock(m_email_lock);
+            callbacksCopy = m_email_conversation_callbacks;
+        }
+        callUpdated<ConversationsChangeCallback, EventConversations>(
+                callbacksCopy, event);
+    }
+    else {
+        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+    }
+}
+
+void ChangeListenerContainer::callConversationRemoved(EventConversations* event)
+{
+    LoggerD("Entered");
+
+    if(MessageType(SMS) == event->service_type ||
+            MessageType(MMS) == event->service_type) {
+        //LoggerD("Calling conversationremoved for ShortConversation");
+        //CCLmap callbacksCopy;
+        //{
+            //std::lock_guard<std::mutex> shortlock(m_short_lock);
+            //LoggerD("m_short_conversation_callbacks.size() = %d",
+                    //m_short_conversation_callbacks.size());
+
+            //callbacksCopy = m_short_conversation_callbacks;
+        //}
+        //callRemoved<ConversationsChangeCallback, EventConversations>(
+                //callbacksCopy, event);
+    }
+    else if(MessageType(EMAIL) == event->service_type) {
+        LoggerD("Calling conversationremoved for Email");
+        CCLmap callbacksCopy;
+        {
+            std::lock_guard<std::mutex> maillock(m_email_lock);
+            LoggerD("m_email_conversation_callbacks.size() = %d",
+                m_email_conversation_callbacks.size());
+
+            callbacksCopy = m_email_conversation_callbacks;
+        }
+        callRemoved<ConversationsChangeCallback, EventConversations>(
+                callbacksCopy, event);
+    }
+    else {
+        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+    }
+}
 
 // -- for folder --
 /*
index 1c4e285..a33c3c0 100644 (file)
@@ -20,8 +20,8 @@
 
 #include "messaging_util.h"
 #include "messages_change_callback.h"
+#include "conversations_change_callback.h"
 
-//#include "ConversationsChangeCallback.h"
 //#include "FoldersChangeCallback.h"
 
 namespace extension {
@@ -38,14 +38,12 @@ struct EventMessages {
 };
 
 //! Data related to ConversationChange event passed to add/update/remove callbacks
-/*
- *struct EventConversations {
- *    int service_id;
- *    MessageType service_type;
- *    ConversationPtrVector items;
- *    // TODO: Filtering support
- *};
- */
+struct EventConversations {
+    int service_id;
+    MessageType service_type;
+    ConversationPtrVector items;
+    // TODO: Filtering support
+};
 
 //! Data related to FolderChange event passed to add/update/remove callbacks
 /*
@@ -65,7 +63,7 @@ template <class T > struct CallbackDataHolder {
 //! Map that stores MessageChangeListeners
 typedef std::map<long, std::shared_ptr<MessagesChangeCallback>> MCLmap;
 //! Map that stores ConversationsChangeListeners
-//typedef std::map<long, std::shared_ptr<ConversationsChangeCallback>> CCLmap;
+typedef std::map<long, std::shared_ptr<ConversationsChangeCallback>> CCLmap;
 //! Map that stores FoldersChangeListeners
 //typedef std::map<long, std::shared_ptr<FoldersChangeCallback>> FCLmap;
 
@@ -86,7 +84,7 @@ class ChangeListenerContainer {
 
         // Interface for listener's manipulation (registration and removal).
         long addMessageChangeListener(std::shared_ptr<MessagesChangeCallback> callback);
-        //long addConversationChangeListener(std::shared_ptr<ConversationsChangeCallback> callback);
+        long addConversationChangeListener(std::shared_ptr<ConversationsChangeCallback> callback);
         //long addFolderChangeListener(std::shared_ptr<FoldersChangeCallback> callback);
         void removeChangeListener(long id);
 
@@ -94,9 +92,9 @@ class ChangeListenerContainer {
         void callMessageAdded(EventMessages* event);
         void callMessageUpdated(EventMessages* event);
         void callMessageRemoved(EventMessages* event);
-        //void callConversationAdded(EventConversations* event);
-        //void callConversationUpdated(EventConversations* event);
-        //void callConversationRemoved(EventConversations* event);
+        void callConversationAdded(EventConversations* event);
+        void callConversationUpdated(EventConversations* event);
+        void callConversationRemoved(EventConversations* event);
         //void callFolderAdded(EventFolders* event);
         //void callFolderUpdated(EventFolders* event);
         //void callFolderRemoved(EventFolders* event);
@@ -122,7 +120,7 @@ class ChangeListenerContainer {
 
         // Callbacks for email service
         MCLmap m_email_message_callbacks;
-        //CCLmap m_email_conversation_callbacks;
+        CCLmap m_email_conversation_callbacks;
         //FCLmap m_email_folder_callbacks;
 
         ChangeListenerContainer();
index 6ffe914..f52d6dc 100644 (file)
@@ -9,7 +9,6 @@ namespace extension {
 namespace messaging {
 
 ConversationCallbackData::ConversationCallbackData():
-        CallbackUserData(),
         m_filter(),
         m_sort(),
         m_limit(0),
@@ -20,6 +19,22 @@ ConversationCallbackData::ConversationCallbackData():
 {
 }
 
+ConversationCallbackData::ConversationCallbackData(long cid, bool keep):
+        m_filter(),
+        m_sort(),
+        m_limit(0),
+        m_offset(0),
+        m_is_error(false),
+        m_account_id(0),
+        m_service_type(UNDEFINED)
+{
+    auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+    picojson::object& o = json->get<picojson::object>();
+    o[JSON_CALLBACK_ID] = picojson::value(static_cast<double>(cid));
+    o[JSON_CALLBACK_KEEP] = picojson::value(keep);
+    setJson(json);
+}
+
 ConversationCallbackData::~ConversationCallbackData()
 {
 }
index 7f71a0b..25ddc28 100644 (file)
@@ -24,6 +24,7 @@ class MessageConversation;
 class ConversationCallbackData: public common::CallbackUserData {
 public:
     ConversationCallbackData();
+    ConversationCallbackData(long cid, bool keep = false);
     virtual ~ConversationCallbackData();
 
     void setFilter(AbstractFilterPtr filter);
diff --git a/src/messaging/conversations_change_callback.cc b/src/messaging/conversations_change_callback.cc
new file mode 100644 (file)
index 0000000..a16fd29
--- /dev/null
@@ -0,0 +1,194 @@
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//#include <JSWebAPIErrorFactory.h>
+//#include <PlatformException.h>
+//#include <JSUtil.h>
+//#include <GlobalContextManager.h>
+
+//#include "MessagingUtil.h"
+//#include "ConversationsChangeCallback.h"
+//#include "JSMessageConversation.h"
+//#include "MessagingUtil.h"
+
+#include "common/logger.h"
+#include "common/platform_exception.h"
+#include "messaging_instance.h"
+#include "messaging_util.h"
+
+#include "conversations_change_callback.h"
+
+namespace extension {
+namespace messaging {
+
+
+const char* CONVERSATIONSADDED = "conversationsadded";
+const char* CONVERSATIONSUPDATED = "conversationsupdated";
+const char* CONVERSATIONSREMOVED = "conversationsremoved";
+
+ConversationsChangeCallback::ConversationsChangeCallback(
+        long cid,
+        int service_id,
+        MessageType service_type) :
+        m_callback_data(cid, true),
+        m_id(service_id),
+        m_msg_type(service_type),
+        m_is_act(true)
+{
+    LoggerD("Entered");
+}
+
+ConversationsChangeCallback::~ConversationsChangeCallback()
+{
+    LoggerD("Entered");
+}
+
+ConversationPtrVector ConversationsChangeCallback::filterConversations(
+        AbstractFilterPtr filter,
+        const ConversationPtrVector& source_conversations)
+{
+    if (filter) {
+        ConversationPtrVector filtered_conversations;
+        ConversationPtrVector::const_iterator it = source_conversations.begin();
+        ConversationPtrVector::const_iterator end_it = source_conversations.end();
+
+        for(int i = 0; it != end_it; ++i, ++it) {
+            const ConversationPtr& conversation = *it;
+            const bool matched = filter->isMatching(conversation.get());
+            if(matched) {
+                filtered_conversations.push_back(conversation);
+            }
+
+            LoggerD("[%d] conversation id:%d", i, conversation->getConversationId());
+            LoggerD("[%d] conversation subject :%s", i, conversation->getSubject().c_str());
+            LoggerD("[%d] matched filter: %s", i, matched ? "YES" : "NO");
+        }
+
+        LoggerD("returning matching %d of %d conversations", filtered_conversations.size(),
+                source_conversations.size());
+
+        return filtered_conversations;
+    }
+    else {
+        return source_conversations;
+    }
+}
+
+void ConversationsChangeCallback::added(
+        const ConversationPtrVector& conversations)
+{
+    LoggerD("Entered conversations.size()=%d", conversations.size());
+    if (!m_is_act) {
+        return;
+    }
+
+    ConversationPtrVector filtered = filterConversations(m_filter, conversations);
+
+    picojson::array array;
+    auto each = [&array] (std::shared_ptr<MessageConversation> c)->void {
+        array.push_back(MessagingUtil::conversationToJson(c));
+    };
+    for_each(filtered.begin(), filtered.end(), each);
+
+    LoggerD("Calling:%s with:%d added conversations", CONVERSATIONSADDED,
+        filtered.size());
+
+    auto json = m_callback_data.getJson();
+    picojson::object& obj = json->get<picojson::object>();
+    obj[JSON_ACTION] = picojson::value(CONVERSATIONSADDED);
+    obj[JSON_DATA] = picojson::value(array);
+    MessagingInstance::getInstance().PostMessage(json->serialize().c_str());
+}
+
+void ConversationsChangeCallback::updated(
+        const ConversationPtrVector& conversations)
+{
+    LoggerD("Entered conversations.size()=%d", conversations.size());
+    if (!m_is_act) {
+        return;
+    }
+
+    ConversationPtrVector filtered = filterConversations(m_filter, conversations);
+
+    picojson::array array;
+    auto each = [&array] (std::shared_ptr<MessageConversation> c)->void {
+        array.push_back(MessagingUtil::conversationToJson(c));
+    };
+    for_each(filtered.begin(), filtered.end(), each);
+
+    LoggerD("Calling:%s with:%d added conversations", CONVERSATIONSUPDATED,
+        filtered.size());
+
+    auto json = m_callback_data.getJson();
+    picojson::object& obj = json->get<picojson::object>();
+    obj[JSON_ACTION] = picojson::value(CONVERSATIONSUPDATED);
+    obj[JSON_DATA] = picojson::value(array);
+    MessagingInstance::getInstance().PostMessage(json->serialize().c_str());
+}
+
+void ConversationsChangeCallback::removed(
+        const ConversationPtrVector& conversations)
+{
+    LoggerD("Entered conversations.size()=%d", conversations.size());
+    if (!m_is_act) {
+        return;
+    }
+
+    ConversationPtrVector filtered = filterConversations(m_filter, conversations);
+
+    picojson::array array;
+    auto each = [&array] (std::shared_ptr<MessageConversation> c)->void {
+        array.push_back(MessagingUtil::conversationToJson(c));
+    };
+    for_each(filtered.begin(), filtered.end(), each);
+
+    LoggerD("Calling:%s with:%d added conversations", CONVERSATIONSREMOVED,
+        filtered.size());
+
+    auto json = m_callback_data.getJson();
+    picojson::object& obj = json->get<picojson::object>();
+    obj[JSON_ACTION] = picojson::value(CONVERSATIONSREMOVED);
+    obj[JSON_DATA] = picojson::value(array);
+    MessagingInstance::getInstance().PostMessage(json->serialize().c_str());
+}
+
+void ConversationsChangeCallback::setFilter(tizen::AbstractFilterPtr filter)
+{
+    m_filter = filter;
+}
+
+tizen::AbstractFilterPtr ConversationsChangeCallback::getFilter() const
+{
+    return m_filter;
+}
+
+int ConversationsChangeCallback::getServiceId() const
+{
+    return m_id;
+}
+
+MessageType ConversationsChangeCallback::getServiceType() const
+{
+    return m_msg_type;
+}
+
+void ConversationsChangeCallback::setActive(bool act) {
+    m_is_act = act;
+}
+
+bool ConversationsChangeCallback::isActive() {
+    return m_is_act;
+}
+
+void ConversationsChangeCallback::setItems(ConversationPtrVector& items)
+{
+    m_items = items;
+}
+ConversationPtrVector ConversationsChangeCallback::getItems()
+{
+    return m_items;
+}
+
+} //namespace messaging
+} //namespace extension
diff --git a/src/messaging/conversations_change_callback.h b/src/messaging/conversations_change_callback.h
new file mode 100644 (file)
index 0000000..2894e8f
--- /dev/null
@@ -0,0 +1,63 @@
+// Copyright 2014 Samsung Electronics Co, Ltd. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef __MESSAGING_CONVERSATIONS_CHANGE_CALLBACK_H__
+#define __MESSAGING_CONVERSATIONS_CHANGE_CALLBACK_H__
+
+#include "MsgCommon/AbstractFilter.h"
+
+#include "conversation_callback_data.h"
+#include "message_conversation.h"
+
+namespace extension {
+namespace messaging {
+
+extern const char* CONVERSATIONSADDED;
+extern const char* CONVERSATIONSUPDATED;
+extern const char* CONVERSATIONSREMOVED;
+
+class ConversationsChangeCallback {
+public:
+    ConversationsChangeCallback(
+            long cid,
+            int service_id,
+            MessageType service_type);
+    virtual ~ConversationsChangeCallback();
+
+    void added(const ConversationPtrVector& conversations);
+    void updated(const ConversationPtrVector& conversations);
+    void removed(const ConversationPtrVector& conversations);
+
+    void setFilter(tizen::AbstractFilterPtr filter);
+    tizen::AbstractFilterPtr getFilter() const;
+
+    int getServiceId() const;
+    MessageType getServiceType() const;
+
+    void setActive(bool act);
+    bool isActive();
+
+    void setItems(ConversationPtrVector& items);
+    ConversationPtrVector getItems();
+private:
+    static ConversationPtrVector filterConversations(
+            tizen::AbstractFilterPtr a_filter,
+            const ConversationPtrVector& a_sourceConversations);
+
+    ConversationCallbackData m_callback_data;
+    tizen::AbstractFilterPtr m_filter;
+    int m_id;
+    MessageType m_msg_type;
+    bool m_is_act;
+    ConversationPtrVector m_items;
+
+};
+
+} //messaging
+} //extension
+
+
+
+
+#endif // __MESSAGING_CONVERSATIONS_CHANGE_CALLBACK_H__
index 748e855..316c6e0 100644 (file)
@@ -314,7 +314,7 @@ std::shared_ptr<MessageConversation> MessageConversation::convertEmailConversati
 
         conversation->m_conversation_id = threadId;
 
-        conversation->m_conversation_type = EMAIL;
+        conversation->m_conversation_type = MessageType::EMAIL;
 
         conversation->m_timestamp = resultMail->date_time;
 
@@ -375,7 +375,7 @@ std::shared_ptr<MessageConversation> MessageConversation::convertConversationStr
 {
     std::shared_ptr<MessageConversation> conversation (new MessageConversation());
 
-    if (EMAIL == msgType) {
+    if (MessageType::EMAIL == msgType) {
         conversation = convertEmailConversationToObject(threadId);
     } else {
         if(handle != NULL) {
index 26de147..bb33936 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "message_storage.h"
 #include "messages_change_callback.h"
+#include "conversations_change_callback.h"
 #include "change_listener_container.h"
 
 #include "common/logger.h"
@@ -40,9 +41,11 @@ long MessageStorage::addMessagesChangeListener(std::shared_ptr<MessagesChangeCal
     return ChangeListenerContainer::getInstance().addMessageChangeListener(callback);
 }
 
-long MessageStorage::addConversationsChangeListener()
+long MessageStorage::addConversationsChangeListener(
+        std::shared_ptr<ConversationsChangeCallback> callback)
 {
     LoggerD("Entered");
+    return ChangeListenerContainer::getInstance().addConversationChangeListener(callback);
 }
 
 long MessageStorage::addFoldersChangeListener()
index 6f69a09..950e178 100644 (file)
@@ -20,6 +20,7 @@ namespace extension {
 namespace messaging {
 
 class MessagesChangeCallback;
+class ConversationsChangeCallback;
 
 class MessageStorage;
 typedef std::shared_ptr<MessageStorage> MessageStoragePtr;
@@ -43,7 +44,7 @@ public:
     // Listeners registration/removal is common for all types of storage
     // and does not have to be overwritten in derived classes.
     long addMessagesChangeListener(std::shared_ptr<MessagesChangeCallback> callback);
-    long addConversationsChangeListener();
+    long addConversationsChangeListener(std::shared_ptr<ConversationsChangeCallback> callback);
     long addFoldersChangeListener();
     void removeChangeListener();
 
index fee6d97..ac88300 100644 (file)
@@ -99,7 +99,9 @@
         'conversation_callback_data.cc',
         'conversation_callback_data.h',
         'folders_callback_data.cc',
-        'folders_callback_data.h'
+        'folders_callback_data.h',
+        'conversations_change_callback.cc',
+        'conversations_change_callback.h'
       ],
       'includes': [
         '../common/pkg-config.gypi',
index fd2a83f..7a00b07 100644 (file)
@@ -1057,7 +1057,7 @@ MessageStorage.prototype.addMessagesChangeListener = function () {
     return result;
 };
 
-MessageStorage.prototype. addConversationsChangeListener = function () {
+MessageStorage.prototype.addConversationsChangeListener = function () {
     var args = validator_.validateArgs(arguments, [
         {name: 'conversationsChangeCallback', type: types_.LISTENER,
                 values: ['conversationsadded', 'conversationsupdated', 'conversationsremoved']},
@@ -1065,26 +1065,14 @@ MessageStorage.prototype. addConversationsChangeListener = function () {
                 optional: true, nullable: true}
     ]);
 
-    var listeners = [];
-    if (args.conversationsChangeCallback.conversationsadded)
-            listeners.push('conversationsadded');
-    if (args.conversationsChangeCallback.conversationsupdated)
-            listeners.push('conversationsupdated');
-    if (args.conversationsChangeCallback.conversationsremoved)
-            listeners.push('conversationsremoved');
+    var self = this;
 
-    bridge({
-        cmd: 'MessageStorage_addConversationsChangeListener',
-        args: {
-            filter: args.filter,
-            listeners: listeners
-        }
-    }).then({
+    var cid = bridge.listener({
         conversationsadded: function (data) {
             if (args.conversationsChangeCallback.conversationsadded) {
                 var conversations = [];
                 data.forEach(function (el) {
-                    conversations.push(new tizen.MessageConversation(el));
+                    conversations.push(new MessageConversation(el));
                 });
                 args.conversationsChangeCallback.conversationsadded.call(null, conversations);
             }
@@ -1093,7 +1081,7 @@ MessageStorage.prototype. addConversationsChangeListener = function () {
             if (args.conversationsChangeCallback.conversationsupdated) {
                 var conversations = [];
                 data.forEach(function (el) {
-                   conversations.push(new tizen.MessageConversation(el));
+                   conversations.push(new MessageConversation(el));
                 });
                 args.conversationsChangeCallback.conversationsupdated.call(null, conversations);
             }
@@ -1102,12 +1090,23 @@ MessageStorage.prototype. addConversationsChangeListener = function () {
             if (args.conversationsChangeCallback.conversationsremoved) {
                 var conversations = [];
                 data.forEach(function (el) {
-                    conversations.push(new tizen.MessageConversation(el));
+                    conversations.push(new MessageConversation(el));
                 });
                 args.conversationsChangeCallback.conversationsremoved.call(null, conversations);
             }
         }
     });
+
+    var result = bridge.sync({
+        cmd: 'MessageStorage_addConversationsChangeListener',
+        cid: cid,
+        args: {
+            filter: args.filter || null,
+            serviceId: self.service.id
+        }
+    });
+
+    return result;
 };
 
 MessageStorage.prototype.addFoldersChangeListener = function () {
index 64d34d3..5c7951d 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "MsgCommon/AbstractFilter.h"
 #include "messages_change_callback.h"
+#include "conversations_change_callback.h"
 #include "messages_callback_user_data.h"
 #include "find_msg_callback_user_data.h"
 #include "folders_callback_data.h"
@@ -134,6 +135,7 @@ MessagingInstance::MessagingInstance()
       REGISTER_SYNC(FUN_MESSAGE_SERVICE_STOP_SYNC, MessageServiceStopSync);
       REGISTER_SYNC(FUN_MESSAGE_SERVICE_SYNC_FOLDER, MessageServiceSyncFolder);
       REGISTER_SYNC(FUN_MESSAGE_STORAGE_ADD_MESSAGES_CHANGE_LISTENER, MessageStorageAddMessagesChangeListener);
+      REGISTER_SYNC(FUN_MESSAGE_STORAGE_ADD_CONVERSATIONS_CHANGE_LISTENER, MessageStorageAddConversationsChangeListener);
       REGISTER_SYNC(FUN_MESSAGE_STORAGE_REMOVE_CHANGE_LISTENER, MessageStorageRemoveChangeListener);
     #undef REGISTER_SYNC
 }
@@ -577,6 +579,22 @@ void MessagingInstance::MessageStorageAddConversationsChangeListener(const picoj
         picojson::object& out)
 {
     LoggerD("Entered");
+    picojson::object data = args.get(JSON_DATA).get<picojson::object>();
+    const long callbackId = static_cast<long>(args.get(JSON_CALLBACK_ID).get<double>());
+
+    int serviceId = static_cast<int>(data.at(FUNCTIONS_HIDDEN_ARGS_SERVICE_ID).get<double>());
+    auto service = MessagingManager::getInstance().getMessageServiceEmail(serviceId);
+
+    std::shared_ptr<ConversationsChangeCallback> callback(new ConversationsChangeCallback(
+                callbackId, serviceId, service->getMsgServiceType()));
+
+    // TODO filter
+    // callback->setFilter(tizen::AbstractFilterPtr(new tizen::AbstractFilter()));
+
+    long op_id = service->getMsgStorage()->addConversationsChangeListener(callback);
+
+    picojson::value v(static_cast<double>(op_id));
+    ReportSuccess(v, out);
 }
 
 void MessagingInstance::MessageStorageAddFolderChangeListener(const picojson::value& args,