[Messaging] removeMessages
authorMaciek Blim <m.blim@samsung.com>
Sat, 20 Dec 2014 10:22:55 +0000 (11:22 +0100)
committerMaciek Blim <m.blim@samsung.com>
Mon, 22 Dec 2014 15:07:30 +0000 (16:07 +0100)
Change-Id: Iab2b4c65c1b8e6e68c8f470526dfc1541013d75b
Signed-off-by: Maciek Blim <m.blim@samsung.com>
16 files changed:
src/messaging/DBus/MessageProxy.cpp
src/messaging/DBus/MessageProxy.h
src/messaging/change_listener_container.cc [new file with mode: 0644]
src/messaging/change_listener_container.h [new file with mode: 0644]
src/messaging/email_manager.cc
src/messaging/email_manager.h
src/messaging/message_storage.h
src/messaging/message_storage_email.cc
src/messaging/message_storage_email.h
src/messaging/messages_callback_user_data.cc [new file with mode: 0644]
src/messaging/messages_callback_user_data.h [new file with mode: 0644]
src/messaging/messages_change_callback.cc [new file with mode: 0644]
src/messaging/messages_change_callback.h [new file with mode: 0644]
src/messaging/messaging.gyp
src/messaging/messaging_api.js
src/messaging/messaging_instance.cc

index 32d478233741f36e30f4d6a33a59433ec6191d59..71373c8b8962abb83dce05f0082813ce9d9d1172 100644 (file)
 
 #include "MessageProxy.h"
 #include "Connection.h"
-#include <Logger.h>
-#include <Message.h>
-#include <MessageEmail.h>
-#include <MessageConversation.h>
-#include <MessageFolder.h>
-#include <ChangeListenerContainer.h>
-#include <EmailManager.h>
-#include <PlatformException.h>
 
-namespace DeviceAPI {
-namespace Messaging {
+#include "common/logger.h"
+#include "common/platform_exception.h"
+
+#include "../message.h"
+#include "../message_email.h"
+
+//#include <MessageConversation.h>
+//#include <MessageFolder.h>
+
+#include "../change_listener_container.h"
+
+#include "../email_manager.h"
+
+namespace extension {
+namespace messaging {
 namespace DBus {
 
 MessageProxy::MessageProxy():
@@ -50,7 +55,7 @@ void MessageProxy::signalCallback(GDBusConnection *connection,
             const gchar *signal_name,
             GVariant *parameters)
 {
-    LOGD("Enter");
+    LoggerD("Enter");
     int status, account_id, object_id, thread_id;
     char* name;
     g_variant_get(parameters, "(iiisi)",
@@ -59,11 +64,11 @@ void MessageProxy::signalCallback(GDBusConnection *connection,
             &object_id,
             &name,
             &thread_id);
-    LOGD("status: %d", status);
-    LOGD("account_id: %d", account_id);
-    LOGD("object_id: %d", object_id);
-    LOGD("name: %s", name);
-    LOGD("thread_id: %d", thread_id);
+    LoggerD("status: %d", status);
+    LoggerD("account_id: %d", account_id);
+    LoggerD("object_id: %d", object_id);
+    LoggerD("name: %s", name);
+    LoggerD("thread_id: %d", thread_id);
 
     try {
         switch (status) {
@@ -92,78 +97,80 @@ void MessageProxy::signalCallback(GDBusConnection *connection,
                 handleMailboxEvent(account_id, object_id, status);
                 break;
             default:
-                LOGD("Unrecognized status: %d", status);
+                LoggerD("Unrecognized status: %d", status);
         }
-    } catch (const Common::BasePlatformException& err) {
-        LOGE("%s (%s)", (err.getName()).c_str(), (err.getMessage()).c_str());
+    } catch (const common::PlatformException& err) {
+        LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str());
     } catch (...) {
-        LOGE("Failed to call callback");
+        LoggerE("Failed to call callback");
     }
     g_free(name);
 }
 
 void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id, int event)
 {
-    LOGD("Enter");
-
-    if(NOTI_MAIL_UPDATE == event) {
-        //getting thread_id from message
-        email_mail_data_t *mail_data = NULL;
-
-        if(EMAIL_ERROR_NONE != email_get_mail_data(mail_id, &mail_data)) {
-            if (mail_data) email_free_mail_data(&mail_data, 1);
-
-            LOGE("Failed to get mail data during setting conversation id in MessageProxy.");
-            return;
-        }
-
-        thread_id = mail_data->thread_id;
-
-        if(EMAIL_ERROR_NONE != email_free_mail_data(&mail_data,1)) {
-            LOGE("Failed to free mail data memory");
-        }
-    }
-
-    email_mail_data_t* mail_data = EmailManager::getInstance().loadMessage(mail_id);
-    if (mail_data == NULL) {
-        throw Common::UnknownException("Failed to load email");
-    }
-    std::shared_ptr<Message> msg = Message::convertPlatformEmailToObject(*mail_data);
-    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);
-    switch (event) {
-        case NOTI_MAIL_ADD:
-            ChangeListenerContainer::getInstance().callMessageAdded(eventMsg);
-            if (conv->getMessageCount() == 1) {
-                LOGD("This thread is new, triggering conversationAdded");
-                ChangeListenerContainer::getInstance().callConversationAdded(eventConv);
-            } else {
-                LOGD("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);
-            break;
-        default:
-            LOGW("Unknown event type: %d", event);
-            break;
-
-    }
-    delete eventMsg;
-    delete eventConv;
-
-    EmailManager::getInstance().freeMessage(mail_data);
+/*
+ *    LoggerD("Enter");
+ *
+ *    if(NOTI_MAIL_UPDATE == event) {
+ *        //getting thread_id from message
+ *        email_mail_data_t *mail_data = NULL;
+ *
+ *        if(EMAIL_ERROR_NONE != email_get_mail_data(mail_id, &mail_data)) {
+ *            if (mail_data) email_free_mail_data(&mail_data, 1);
+ *
+ *            LoggerE("Failed to get mail data during setting conversation id in MessageProxy.");
+ *            return;
+ *        }
+ *
+ *        thread_id = mail_data->thread_id;
+ *
+ *        if(EMAIL_ERROR_NONE != email_free_mail_data(&mail_data,1)) {
+ *            LoggerE("Failed to free mail data memory");
+ *        }
+ *    }
+ *
+ *    email_mail_data_t* mail_data = EmailManager::getInstance().loadMessage(mail_id);
+ *    if (mail_data == NULL) {
+ *        throw common::UnknownException("Failed to load email");
+ *    }
+ *    std::shared_ptr<Message> msg = Message::convertPlatformEmailToObject(*mail_data);
+ *    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);
+ *    switch (event) {
+ *        case NOTI_MAIL_ADD:
+ *            ChangeListenerContainer::getInstance().callMessageAdded(eventMsg);
+ *            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);
+ *            break;
+ *        default:
+ *            LoggerW("Unknown event type: %d", event);
+ *            break;
+ *
+ *    }
+ *    delete eventMsg;
+ *    delete eventConv;
+ *
+ *    EmailManager::getInstance().freeMessage(mail_data);
+ */
 }
 
 std::vector<int> getMailIds(const std::string& idsString)
@@ -177,7 +184,7 @@ std::vector<int> getMailIds(const std::string& idsString)
             std::stringstream stream(item);
             stream >> id;
             if (stream) {
-                LOGD("Mail delete id: %d", id);
+                LoggerD("Mail delete id: %d", id);
                 ids.push_back(id);
             }
         }
@@ -187,10 +194,10 @@ std::vector<int> getMailIds(const std::string& idsString)
 
 void MessageProxy::handleEmailRemoveEvent(int account_id, const std::string& idsString)
 {
-    LOGD("Enter");
+    LoggerD("Enter");
     std::vector<int> ids = getMailIds(idsString);
     if (ids.empty()) {
-        LOGD("Mail id list is empty.");
+        LoggerD("Mail id list is empty.");
         return;
     }
     EventMessages* eventMsg = new EventMessages();
@@ -211,10 +218,10 @@ void MessageProxy::handleEmailRemoveEvent(int account_id, const std::string& ids
 void MessageProxy::notifyEmailManager(const std::string& idsString,
         email_noti_on_storage_event status)
 {
-    LOGD("Enter");
+    LoggerD("Enter");
     std::vector<int> ids = getMailIds(idsString);
     if (ids.empty()) {
-        LOGD("Mail id list is empty.");
+        LoggerD("Mail id list is empty.");
         return;
     }
     EmailManager::getInstance().removeStatusCallback(ids, status);
@@ -222,69 +229,73 @@ void MessageProxy::notifyEmailManager(const std::string& idsString,
 
 void MessageProxy::handleThreadRemoveEvent(int account_id, int thread_id)
 {
-    LOGD("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;
+/*
+ *    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;
+ */
 }
 
 void MessageProxy::handleMailboxEvent(int account_id, int mailbox_id, int event)
 {
-    LOGD("Enter");
-
-    EventFolders* eventFolder = new EventFolders();
-    eventFolder->service_type = MessageType::EMAIL;
-    eventFolder->service_id = account_id;
-    FolderPtr folder;
-    if (event == NOTI_MAILBOX_DELETE) {
-        //this event is triggered after mailbox is removed
-        //so we just create folder with id
-        folder.reset(new MessageFolder(std::to_string(mailbox_id),
-                "", //parent_id
-                "", //service_id
-                "", //content_type
-                "", //name
-                "", //path
-                MessageFolderType::MESSAGE_FOLDER_TYPE_NOTSTANDARD,
-                false));
-    } else {
-        email_mailbox_t* mail_box = NULL;
-        if (EMAIL_ERROR_NONE != email_get_mailbox_by_mailbox_id(mailbox_id, &mail_box)) {
-            LOGE("Mailbox not retrieved");
-            delete eventFolder;
-            throw Common::UnknownException("Failed to load mailbox");
-        }
-        folder.reset(new MessageFolder(*mail_box));
-        if (EMAIL_ERROR_NONE != email_free_mailbox(&mail_box, 1)) {
-            LOGD("Failed to free email_free_mailbox");
-        }
-    }
-    eventFolder->items.push_back(folder);
-    switch (event) {
-        case NOTI_MAILBOX_ADD:
-            ChangeListenerContainer::getInstance().callFolderAdded(eventFolder);
-            break;
-        case NOTI_MAILBOX_UPDATE:
-        case NOTI_MAILBOX_FIELD_UPDATE:
-            ChangeListenerContainer::getInstance().callFolderUpdated(eventFolder);
-            break;
-        case NOTI_MAILBOX_DELETE:
-            ChangeListenerContainer::getInstance().callFolderRemoved(eventFolder);
-            break;
-        default:
-            LOGW("Unknown event type: %d", event);
-    }
-    delete eventFolder;
+/*
+ *    LoggerD("Enter");
+ *
+ *    EventFolders* eventFolder = new EventFolders();
+ *    eventFolder->service_type = MessageType::EMAIL;
+ *    eventFolder->service_id = account_id;
+ *    FolderPtr folder;
+ *    if (event == NOTI_MAILBOX_DELETE) {
+ *        //this event is triggered after mailbox is removed
+ *        //so we just create folder with id
+ *        folder.reset(new MessageFolder(std::to_string(mailbox_id),
+ *                "", //parent_id
+ *                "", //service_id
+ *                "", //content_type
+ *                "", //name
+ *                "", //path
+ *                MessageFolderType::MESSAGE_FOLDER_TYPE_NOTSTANDARD,
+ *                false));
+ *    } else {
+ *        email_mailbox_t* mail_box = NULL;
+ *        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");
+ *        }
+ *        folder.reset(new MessageFolder(*mail_box));
+ *        if (EMAIL_ERROR_NONE != email_free_mailbox(&mail_box, 1)) {
+ *            LoggerD("Failed to free email_free_mailbox");
+ *        }
+ *    }
+ *    eventFolder->items.push_back(folder);
+ *    switch (event) {
+ *        case NOTI_MAILBOX_ADD:
+ *            ChangeListenerContainer::getInstance().callFolderAdded(eventFolder);
+ *            break;
+ *        case NOTI_MAILBOX_UPDATE:
+ *        case NOTI_MAILBOX_FIELD_UPDATE:
+ *            ChangeListenerContainer::getInstance().callFolderUpdated(eventFolder);
+ *            break;
+ *        case NOTI_MAILBOX_DELETE:
+ *            ChangeListenerContainer::getInstance().callFolderRemoved(eventFolder);
+ *            break;
+ *        default:
+ *            LoggerW("Unknown event type: %d", event);
+ *    }
+ *    delete eventFolder;
+ */
 }
 
-} //DBus
-} //Messaging
-} //DeviceAPI
+} //namespace DBus
+} //namespace messaging
+} //namespace extension
index 7b6d456ebeeb5efd28f0d20a8b4e2de74c6530b3..1b8f040f9a47a7937726dcb27acaca35fe752f79 100644 (file)
 #include <gio/gio.h>
 #include <memory>
 #include <string>
+#include <sstream>
 #include <email-types.h>
 #include "Proxy.h"
 
-namespace DeviceAPI {
-namespace Messaging {
+namespace extension {
+namespace messaging {
 namespace DBus {
 
 class MessageProxy: public Proxy {
@@ -57,9 +58,9 @@ protected:
 
 typedef std::shared_ptr<MessageProxy> MessageProxyPtr;
 
-} //DBus
-} //Messaging
-} //DeviceAPI
+} //namespace DBus
+} //namespace messaging
+} //namespace extension
 
 #endif /* __TIZEN_MESSAGE_PROXY_H */
 
diff --git a/src/messaging/change_listener_container.cc b/src/messaging/change_listener_container.cc
new file mode 100644 (file)
index 0000000..a191190
--- /dev/null
@@ -0,0 +1,470 @@
+// 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 "change_listener_container.h"
+
+#include "email_manager.h"
+//#include "ShortMsgManager.h"
+
+namespace extension {
+namespace messaging {
+
+ChangeListenerContainer& ChangeListenerContainer::getInstance()
+{
+    EmailManager::getInstance(); //make sure that callbacks are registered in email-service
+    //ShortMsgManager::getInstance(); //make sure that callbacks are registered in msg-service
+    static ChangeListenerContainer clc;
+    return clc;
+}
+
+ChangeListenerContainer::ChangeListenerContainer():
+        m_current_id(0)
+{
+    LoggerD("Entered");
+    // call getNextId() function to properly initialize static mutex inside
+    getNextId();
+}
+
+// --- Listeners registration functions ---
+/*
+ *long ChangeListenerContainer::addMessageChangeListener(
+ *        std::shared_ptr<MessagesChangeCallback> 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_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<std::mutex> 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(
+ *        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(
+ *        std::shared_ptr<FoldersChangeCallback> 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_folder_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_folder_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;
+ *}
+ */
+
+// --- listeners removal ---
+void ChangeListenerContainer::removeChangeListener(long id)
+{
+    LoggerD("Entered");
+    // Lock both types of collections - id does not indicate service type
+    // TODO: consider additional map<listener_id, service_type> or
+    //       map<lister_id, map<>&> to provide faster and less complicated removal
+    std::lock_guard<std::mutex> shortlock(m_short_lock);
+    std::lock_guard<std::mutex> maillock(m_email_lock);
+    LoggerD("Locks done");
+    if(id<0 || id > m_current_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);
+     *}
+     */
+    /*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 {
+        LoggerW("WatchId %d not found", id);
+    }
+}
+
+// --- Callback invoking functions ---
+// -- for message --
+/*
+ *void ChangeListenerContainer::callMessageAdded(EventMessages* event)
+ *{
+ *    LoggerD("Entered");
+ *
+ *    if(MessageType(SMS) == event->service_type ||
+ *            MessageType(MMS) == event->service_type) {
+ *        LoggerD("Calling messageadded for ShortMessage");
+ *        MCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> shortlock(m_short_lock);
+ *            callbacksCopy = m_short_message_callbacks;
+ *        }
+ *        callAdded<MessagesChangeCallback, EventMessages>(
+ *                callbacksCopy, event);
+ *    }
+ *    else if(MessageType(EMAIL) == event->service_type) {
+ *        LoggerD("Calling messageadded for Email");
+ *        MCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> maillock(m_email_lock);
+ *            callbacksCopy = m_email_message_callbacks;
+ *        }
+ *        callAdded<MessagesChangeCallback, EventMessages>(
+ *                callbacksCopy, event);
+ *    }
+ *    else {
+ *        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+ *    }
+ *}
+ */
+
+/*
+ *void ChangeListenerContainer::callMessageUpdated(EventMessages* event)
+ *{
+ *    LoggerD("Entered");
+ *
+ *    if(MessageType(SMS) == event->service_type ||
+ *            MessageType(MMS) == event->service_type) {
+ *        LoggerD("Calling messageupdated for ShortMessage");
+ *        MCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> shortlock(m_short_lock);
+ *            callbacksCopy = m_short_message_callbacks;
+ *        }
+ *        callUpdated<MessagesChangeCallback, EventMessages>(
+ *                callbacksCopy, event);
+ *    }
+ *    else if(MessageType(EMAIL) == event->service_type) {
+ *        LoggerD("Calling messageupdated for Email");
+ *        MCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> maillock(m_email_lock);
+ *            callbacksCopy = m_email_message_callbacks;
+ *        }
+ *        callUpdated<MessagesChangeCallback, EventMessages>(
+ *                callbacksCopy, event);
+ *    }
+ *    else {
+ *        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+ *    }
+ *}
+ */
+
+void ChangeListenerContainer::callMessageRemoved(EventMessages* event)
+{
+    LoggerD("Entered");
+
+    if(MessageType(SMS) == event->service_type ||
+            MessageType(MMS) == event->service_type) {
+        /*
+         *LoggerD("Calling messageremoved for ShortMessage");
+         *MCLmap callbacksCopy;
+         *{
+         *    std::lock_guard<std::mutex> shortlock(m_short_lock);
+         *    callbacksCopy = m_short_message_callbacks;
+         *}
+         *callRemoved<MessagesChangeCallback, EventMessages>(
+         *        callbacksCopy, event);
+         */
+    }
+    else if(MessageType(EMAIL) == event->service_type) {
+        LoggerD("Calling messageremoved for Email");
+        MCLmap callbacksCopy;
+        {
+            std::lock_guard<std::mutex> maillock(m_email_lock);
+            callbacksCopy = m_email_message_callbacks;
+        }
+        callRemoved<MessagesChangeCallback, EventMessages>(
+                callbacksCopy, event);
+    }
+    else {
+        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+    }
+}
+
+// -- 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::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 --
+/*
+ *void ChangeListenerContainer::callFolderAdded(EventFolders* event)
+ *{
+ *    LoggerD("Entered");
+ *
+ *    if(MessageType(SMS) == event->service_type ||
+ *            MessageType(MMS) == event->service_type) {
+ *        LoggerD("Calling folderadded for ShortMessage");
+ *        FCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> shortlock(m_short_lock);
+ *            callbacksCopy = m_short_folder_callbacks;
+ *        }
+ *        callAdded<FoldersChangeCallback, EventFolders>(
+ *                m_short_folder_callbacks, event);
+ *    }
+ *    else if(MessageType(EMAIL) == event->service_type) {
+ *        LoggerD("Calling folderadded for Email");
+ *        FCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> maillock(m_email_lock);
+ *            callbacksCopy = m_email_folder_callbacks;
+ *        }
+ *        callAdded<FoldersChangeCallback, EventFolders>(
+ *                callbacksCopy, event);
+ *    }
+ *    else {
+ *        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+ *    }
+ *}
+ */
+
+
+/*
+ *void ChangeListenerContainer::callFolderUpdated(EventFolders* event)
+ *{
+ *    LoggerD("Entered");
+ *
+ *    if(MessageType(SMS) == event->service_type ||
+ *            MessageType(MMS) == event->service_type) {
+ *        LoggerD("Calling folderupdated for ShortFolder");
+ *        FCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> shortlock(m_short_lock);
+ *            callbacksCopy = m_short_folder_callbacks;
+ *        }
+ *        callUpdated<FoldersChangeCallback, EventFolders>(
+ *                callbacksCopy, event);
+ *    }
+ *    else if(MessageType(EMAIL) == event->service_type) {
+ *        LoggerD("Calling folderupdated for Email");
+ *        FCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> maillock(m_email_lock);
+ *            callbacksCopy = m_email_folder_callbacks;
+ *        }
+ *        callUpdated<FoldersChangeCallback, EventFolders>(
+ *                callbacksCopy, event);
+ *    }
+ *    else {
+ *        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+ *    }
+ *}
+ */
+
+/*
+ *void ChangeListenerContainer::callFolderRemoved(EventFolders* event)
+ *{
+ *    LoggerD("Entered");
+ *
+ *    if(MessageType(SMS) == event->service_type ||
+ *            MessageType(MMS) == event->service_type) {
+ *        LoggerD("Calling folderremoved for ShortFolder");
+ *        FCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> shortlock(m_short_lock);
+ *            callbacksCopy = m_short_folder_callbacks;
+ *        }
+ *        callRemoved<FoldersChangeCallback, EventFolders>(
+ *                callbacksCopy, event);
+ *    }
+ *    else if(MessageType(EMAIL) == event->service_type) {
+ *        LoggerD("Calling folderremoved for Email");
+ *        FCLmap callbacksCopy;
+ *        {
+ *            std::lock_guard<std::mutex> maillock(m_email_lock);
+ *            callbacksCopy = m_email_folder_callbacks;
+ *        }
+ *        callRemoved<FoldersChangeCallback, EventFolders>(
+ *                callbacksCopy, event);
+ *    }
+ *    else {
+ *        LoggerW("Invalid event type (%d) - no callback called.", event->service_type);
+ *    }
+ *}
+ */
+
+int ChangeListenerContainer::getNextId() {
+    // mutex is created only on first call (first call added to constructor
+    // to initialize mutex correctly
+    static std::mutex id_mutex;
+    std::lock_guard<std::mutex> idlock(id_mutex);
+
+    return m_current_id++;
+}
+
+} //namespace messaging
+} //namespace extension
diff --git a/src/messaging/change_listener_container.h b/src/messaging/change_listener_container.h
new file mode 100644 (file)
index 0000000..ffbe943
--- /dev/null
@@ -0,0 +1,247 @@
+// 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 __TIZEN_CHANGE_LISTENER_CONTAINER_H__
+#define __TIZEN_CHANGE_LISTENER_CONTAINER_H__
+
+#include <memory>
+#include <mutex>
+#include <vector>
+#include <map>
+
+#include "common/logger.h"
+#include "common/platform_exception.h"
+
+#include "message.h"
+
+//#include "MessageConversation.h"
+//#include "MessageFolder.h"
+
+#include "messaging_util.h"
+#include "messages_change_callback.h"
+
+//#include "ConversationsChangeCallback.h"
+//#include "FoldersChangeCallback.h"
+
+namespace extension {
+namespace messaging {
+
+//! Data related to MessageChange event passed to add/update/remove callbacks
+struct EventMessages {
+    int service_id;
+    MessageType service_type;
+    MessagePtrVector items;
+    // TODO Uncomment when removing conversations
+    // ConversationPtrVector removed_conversations;
+    // TODO: Filtering support
+};
+
+//! Data related to ConversationChange event passed to add/update/remove callbacks
+/*
+ *struct EventConversations {
+ *    int service_id;
+ *    MessageType service_type;
+ *    ConversationPtrVector items;
+ *    // TODO: Filtering support
+ *};
+ */
+
+//! Data related to FolderChange event passed to add/update/remove callbacks
+/*
+ *struct EventFolders {
+ *    int service_id;
+ *    MessageType service_type;
+ *    FolderPtrVector items;
+ *    // TODO: Filtering support
+ *};
+ */
+
+template <class T > struct CallbackDataHolder {
+    std::shared_ptr<T> ptr;
+    int operation_type;
+};
+
+//! 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;
+//! Map that stores FoldersChangeListeners
+//typedef std::map<long, std::shared_ptr<FoldersChangeCallback>> FCLmap;
+
+
+/**
+ * Singleton class for managing (storing and calling) ChangeListeners for
+ * short message (SMS/MMS) service and email service.
+ *
+ * Two mutexes used to lock separately addition and searching of Short and
+ * Email message related listeners. Listeneres removal functions locks access
+ * to both types of listeners (havind listener id only it is not possible
+ * to determine message (service) type.
+ */
+class ChangeListenerContainer {
+    public:
+        static ChangeListenerContainer& getInstance();
+
+
+        // Interface for listener's manipulation (registration and removal).
+        //long addMessageChangeListener(std::shared_ptr<MessagesChangeCallback> callback);
+        //long addConversationChangeListener(std::shared_ptr<ConversationsChangeCallback> callback);
+        //long addFolderChangeListener(std::shared_ptr<FoldersChangeCallback> callback);
+        void removeChangeListener(long id);
+
+        // Methods used to invoke registered listeners
+        //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 callFolderAdded(EventFolders* event);
+        //void callFolderUpdated(EventFolders* event);
+        //void callFolderRemoved(EventFolders* event);
+
+    private:
+        //! Highest used id (in most cases id of last registered listener)
+        long m_current_id;
+        //! Mutex for preventing race conditions on SMS/MMS callbacks collection
+        std::mutex m_short_lock;
+        //! Mutex for preventing race conditions on email callbacks collection
+        std::mutex m_email_lock;
+
+        //! Functions for listener id incrementation with thread safe mutex locking
+        int getNextId();
+
+        /* Callbacks for emails and short messages should be stored in separate
+         * collections to simplyfy adding ang searching on call */
+
+        // Callbacks for short messages service
+        //MCLmap m_short_message_callbacks;
+        //CCLmap m_short_conversation_callbacks;
+        //FCLmap m_short_folder_callbacks;
+
+        // Callbacks for email service
+        MCLmap m_email_message_callbacks;
+        //CCLmap m_email_conversation_callbacks;
+        //FCLmap m_email_folder_callbacks;
+
+        ChangeListenerContainer();
+
+        template<class T> static bool removeCallbackIfExists(
+                std::map<long,std::shared_ptr<T>>& collection, long id ) {
+            LoggerD("Entered");
+
+            auto itr = collection.find(id);
+            if ( itr != collection.end()) {
+                itr->second->setActive(false);
+                collection.erase(id);
+                return true;
+            } else {
+                LoggerE("Removing callback which does not belong to the current context is not allowed.");
+                throw common::NotFoundException(
+                        "Removing callback which does not belong to the current context is not allowed.");
+            }
+            return false;
+        }
+
+        /* Templates below written for code reusage (each template is used
+         * 2 times in each callXxxx[Added | Removed | Updated] function. */
+
+        /**
+         * Template function for calling "added" callback for all listeners
+         * from given collection with given event.
+         * */
+        /*
+         *template<class T, class U> void callAdded(
+         *        std::map<long,std::shared_ptr<T>>& collection,
+         *        U* event) {
+         *    typename std::map<long,std::shared_ptr<T>>::iterator itstart = collection.begin();
+         *    typename std::map<long,std::shared_ptr<T>>::iterator itend = collection.end();
+         *    try {
+         *        for (; itstart != itend; ++itstart) {
+         *            auto callback = (*itstart).second;
+         *            if (callback->getServiceType() == event->service_type
+         *                    && callback->getServiceId() == event->service_id) {
+         *                LoggerD("Found callback for given service id (%d) and type (%d)",
+         *                        event->service_id, event->service_type);
+         *                //@todo filter msgs
+         *                callback->added(event->items);
+         *            }
+         *        }
+         *    }catch (const Common::BasePlatformException &err) {
+         *        LoggerE("callAdded failed, %s: %s", err.getName().c_str(),
+         *                err.getMessage().c_str());
+         *    }
+         *    catch (...) {
+         *        LoggerE("callAdded failed");
+         *    }
+         *}
+         */
+
+        /**
+         * Template function for calling "updated" callback for all listeners
+         * from given collection with given event.
+         * */
+        /*
+         *template<class T, class U> void callUpdated(
+         *        std::map<long,std::shared_ptr<T>>& collection,
+         *        U* event) {
+         *    typename std::map<long,std::shared_ptr<T>>::iterator itstart = collection.begin();
+         *    typename std::map<long,std::shared_ptr<T>>::iterator itend = collection.end();
+         *    try {
+         *        for (; itstart != itend; ++itstart) {
+         *            auto callback = (*itstart).second;
+         *            if (callback->getServiceType() == event->service_type
+         *                    && callback->getServiceId() == event->service_id) {
+         *                LoggerD("Found callback for given service id (%d) and type (%d)",
+         *                        event->service_id, event->service_type);
+         *                //@todo filter msgs
+         *                callback->updated(event->items);
+         *            }
+         *        }
+         *    }catch (const Common::BasePlatformException &err) {
+         *        LoggerE("callUpdated failed, %s: %s", err.getName().c_str(),
+         *                err.getMessage().c_str());
+         *    }
+         *    catch (...) {
+         *        LoggerE("callUpdated failed");
+         *    }
+         *}
+         */
+
+        /**
+         * Template function for calling "removed" callback for all listeners
+         * from given collection with given event.
+         * */
+
+        template<class T, class U> void callRemoved(
+                std::map<long,std::shared_ptr<T>>& collection,
+                U* event) {
+            typename std::map<long,std::shared_ptr<T>>::iterator itstart = collection.begin();
+            typename std::map<long,std::shared_ptr<T>>::iterator itend = collection.end();
+            try {
+                for (; itstart != itend; ++itstart) {
+                    auto callback = (*itstart).second;
+                    if (callback->getServiceType() == event->service_type
+                            && callback->getServiceId() == event->service_id) {
+                        LoggerD("Found callback for given service id (%d) and type (%d)",
+                                event->service_id, event->service_type);
+                        //@todo filter msgs
+                        callback->removed(event->items);
+                    }
+                }
+            }catch (const common::PlatformException &err) {
+                LoggerE("callRemoved failed, %s: %s", err.name().c_str(),
+                        err.message().c_str());
+            }
+            catch (...) {
+                LoggerE("callRemoved failed");
+            }
+        }
+};
+
+
+} //namespace messaging
+} //namespace extension
+
+#endif // __TIZEN_CHANGE_LISTENER_CONTAINER_H__
index 0fac2ba120be1c1f7ae13b9d5afec0b38d01d170..1786234aae6b0df0c1ba1f49beb26131e7ca6b99 100644 (file)
@@ -115,7 +115,7 @@ EmailManager::EmailManager()
                                         DBus::Proxy::DBUS_IFACE_NETWORK_STATUS);
     if (!m_proxy_load_body) {
         LoggerE("Load body proxy is null");
-        throw common::UnknownException("Load body proxy is null");
+        throw UnknownException("Load body proxy is null");
     }
     m_proxy_load_body->signalSubscribe();
 
@@ -127,18 +127,18 @@ EmailManager::EmailManager()
 //        throw Common::UnknownException("Load attachment proxy is null");
 //    }
 //    m_proxy_load_attachment->signalSubscribe();
-//
-//    m_proxy_messageStorage = std::make_shared<DBus::MessageProxy>();
-//    if (!m_proxy_messageStorage) {
-//        LoggerE("Message proxy is null");
-//        throw Common::UnknownException("Message proxy is null");
-//    }
-//    m_proxy_messageStorage->signalSubscribe();
+
+    m_proxy_messageStorage = std::make_shared<DBus::MessageProxy>();
+    if (!m_proxy_messageStorage) {
+        LoggerE("Message proxy is null");
+        throw UnknownException("Message proxy is null");
+    }
+    m_proxy_messageStorage->signalSubscribe();
 
     m_proxy_send = std::make_shared<DBus::SendProxy>();
     if (!m_proxy_send) {
         LoggerE("Send proxy is null");
-        throw common::UnknownException("Send proxy is null");
+        throw UnknownException("Send proxy is null");
     }
     m_proxy_send->signalSubscribe();
 }
@@ -804,148 +804,144 @@ void EmailManager::stopSync(long op_id)
 
 //################################## ^stopSync #################################
 
-//void removeEmailCompleteCB(MessagesCallbackUserData* callback)
-//{
-//    LoggerD("Entered");
-//    if (!callback) {
-//        LoggerE("Callback is null");
-//        return;
-//    }
-//
-//    JSContextRef context = callback->getContext();
-//    if (!GlobalContextManager::getInstance()->isAliveGlobalContext(context)) {
-//        LoggerE("context was closed");
-//        delete callback;
-//        callback = NULL;
-//        return;
-//    }
-//
-//    try {
-//        if (callback->isError()) {
-//            LoggerD("Calling error callback");
-//            JSObjectRef errobj = JSWebAPIErrorFactory::makeErrorObject(context,
-//                    callback->getErrorName(),
-//                    callback->getErrorMessage());
-//            callback->callErrorCallback(errobj);
-//        } else {
-//            LoggerD("Calling success callback");
-//            callback->callSuccessCallback();
-//        }
-//    } catch (const BasePlatformException& err) {
-//        LoggerE("Error while calling removeEmail callback: %s (%s)",
-//                (err.getName()).c_str(), (err.getMessage()).c_str());
-//    } catch (...) {
-//        LoggerE("Unknown error when calling removeEmail callback.");
-//    }
-//
-//    delete callback;
-//    callback = NULL;
-//}
-//
-//EmailManager::DeleteReqVector::iterator EmailManager::getDeleteRequest(
-//        const std::vector<int> &ids)
-//{
-//    for (auto idIt = ids.begin(); idIt != ids.end(); ++idIt) {
-//        for (auto reqIt = m_deleteRequests.begin(); reqIt != m_deleteRequests.end(); ++reqIt) {
-//            MessagePtrVector msgs = reqIt->callback->getMessages();
-//            for (auto msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) {
-//                if ((*msgIt)->getId() == *idIt) {
-//                    return reqIt;
-//                }
-//            }
-//        }
-//    }
-//    return m_deleteRequests.end();
-//}
-//
-//void EmailManager::removeStatusCallback(const std::vector<int> &ids,
-//            email_noti_on_storage_event status)
-//{
-//    LoggerD("Enter");
-//    std::lock_guard<std::mutex> lock(m_mutex);
-//    DeleteReqVector::iterator it = getDeleteRequest(ids);
-//    if (it != m_deleteRequests.end()) {
-//        LoggerD("Found request");
-//        if (NOTI_MAIL_DELETE_FINISH == status) {
-//            LoggerD("Successfully removed %d mails", ids.size());
-//            it->messagesDeleted += ids.size();
-//        }
-//        MessagesCallbackUserData* callback = it->callback;
-//        if (NOTI_MAIL_DELETE_FAIL == status) {
-//            LoggerD("Failed to remove mail");
-//            callback->setError(JSWebAPIErrorFactory::UNKNOWN_ERROR, "Messages remove failed");
-//        }
-//        //if one of mails failed, call error callback
-//        //if all mails are deleted, call success.
-//        // >= is used in case of duplicated dbus messages
-//        if (NOTI_MAIL_DELETE_FAIL == status ||
-//                static_cast<unsigned int>(it->messagesDeleted) >= it->callback->getMessages().size()) {
-//            LoggerD("Calling callback");
-//            m_deleteRequests.erase(it);
-//            m_mutex.unlock();
-//            removeEmailCompleteCB(callback);
-//        } else {
-//            LoggerD("Not all messages are removed, waiting for next callback");
-//        }
-//    } else {
-//        LoggerD("Request not found, ignoring");
-//    }
-//}
-//
-//void EmailManager::removeMessages(MessagesCallbackUserData* callback)
-//{
-//    LoggerD("Entered");
-//
-//    if (!callback){
-//        LoggerE("Callback is null");
-//        return;
-//    }
-//
-//    int error;
-//    email_mail_data_t *mail = NULL;
-//
-//    try {
-//        std::lock_guard<std::mutex> lock(m_mutex);
-//        std::vector<std::shared_ptr<Message>> 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");
-//            }
-//
-//            //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 BasePlatformException& err) {
-//        LoggerE("%s (%s)", (err.getName()).c_str(), (err.getMessage()).c_str());
-//        callback->setError(err.getName(), err.getMessage());
-//        removeEmailCompleteCB(callback);
-//    } catch (...) {
-//        LoggerE("Messages remove failed");
-//        callback->setError(JSWebAPIErrorFactory::UNKNOWN_ERROR, "Messages remove failed");
-//        removeEmailCompleteCB(callback);
-//    }
-//}
-//
+void removeEmailCompleteCB(MessagesCallbackUserData* callback)
+{
+    LoggerD("Entered");
+    if (!callback) {
+        LoggerE("Callback is null");
+        return;
+    }
+
+    try {
+        if (callback->isError()) {
+            LoggerD("Calling error callback");
+            MessagingInstance::getInstance().PostMessage(
+                    callback->getJson()->serialize().c_str());
+        } else {
+            LoggerD("Calling success callback");
+
+            auto json = callback->getJson();
+            picojson::object& obj = json->get<picojson::object>();
+            obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS);
+            MessagingInstance::getInstance().PostMessage(json->serialize().c_str());
+        }
+    } 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.");
+    }
+
+    delete callback;
+    callback = NULL;
+}
+
+EmailManager::DeleteReqVector::iterator EmailManager::getDeleteRequest(
+        const std::vector<int> &ids)
+{
+    for (auto idIt = ids.begin(); idIt != ids.end(); ++idIt) {
+        for (auto reqIt = m_deleteRequests.begin(); reqIt != m_deleteRequests.end(); ++reqIt) {
+            MessagePtrVector msgs = reqIt->callback->getMessages();
+            for (auto msgIt = msgs.begin(); msgIt != msgs.end(); ++msgIt) {
+                if ((*msgIt)->getId() == *idIt) {
+                    return reqIt;
+                }
+            }
+        }
+    }
+    return m_deleteRequests.end();
+}
+
+void EmailManager::removeStatusCallback(const std::vector<int> &ids,
+            email_noti_on_storage_event status)
+{
+    LoggerD("Enter");
+    std::lock_guard<std::mutex> lock(m_mutex);
+    DeleteReqVector::iterator it = getDeleteRequest(ids);
+    if (it != m_deleteRequests.end()) {
+        LoggerD("Found request");
+        if (NOTI_MAIL_DELETE_FINISH == status) {
+            LoggerD("Successfully removed %d mails", ids.size());
+            it->messagesDeleted += ids.size();
+        }
+        MessagesCallbackUserData* callback = it->callback;
+        if (NOTI_MAIL_DELETE_FAIL == status) {
+            LoggerD("Failed to remove mail");
+            UnknownException e("Messages remove failed");
+            callback->setError(e.name(), e.message());
+        }
+        //if one of mails failed, call error callback
+        //if all mails are deleted, call success.
+        // >= is used in case of duplicated dbus messages
+        if (NOTI_MAIL_DELETE_FAIL == status ||
+                static_cast<unsigned int>(it->messagesDeleted) >= it->callback->getMessages().size()) {
+            LoggerD("Calling callback");
+            m_deleteRequests.erase(it);
+            m_mutex.unlock();
+            removeEmailCompleteCB(callback);
+        } else {
+            LoggerD("Not all messages are removed, waiting for next callback");
+        }
+    } else {
+        LoggerD("Request not found, ignoring");
+    }
+}
+
+void EmailManager::removeMessages(MessagesCallbackUserData* callback)
+{
+    LoggerD("Entered");
+
+    if (!callback){
+        LoggerE("Callback is null");
+        return;
+    }
+
+    int error;
+    email_mail_data_t *mail = NULL;
+
+    try {
+        std::lock_guard<std::mutex> lock(m_mutex);
+        std::vector<std::shared_ptr<Message>> 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");
+            }
+
+            //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);
+    }
+}
+
 //void EmailManager::updateMessages(MessagesCallbackUserData* callback)
 //{
 //    LoggerD("Entered");
index 4e55266d32b3ec5864b8ee23f3bb9b9da799b492..5928fdeb6689d5f3c58f346f39b1a70856952c48 100644 (file)
@@ -43,7 +43,7 @@
 #include "DBus/SyncProxy.h"
 #include "DBus/LoadBodyProxy.h"
 //#include "DBus/LoadAttachmentProxy.h"
-//#include "DBus/MessageProxy.h"
+#include "DBus/MessageProxy.h"
 #include "DBus/SendProxy.h"
 
 namespace extension {
@@ -60,7 +60,7 @@ public:
     static EmailManager& getInstance();
 
     void addDraftMessage(MessageCallbackUserData* callback);
-//    void removeMessages(MessagesCallbackUserData* callback);
+    void removeMessages(MessagesCallbackUserData* callback);
 //    void updateMessages(MessagesCallbackUserData* callback);
     void findMessages(FindMsgCallbackUserData* callback);
 //    void findConversations(ConversationCallbackData* callback);
@@ -70,9 +70,9 @@ public:
     void sendMessage(MessageRecipientsCallbackData* callback);
     void sendStatusCallback(int mail_id, email_noti_on_network_event status,
             int error_code);
-//    void removeStatusCallback(const std::vector<int> &ids,
-//            email_noti_on_storage_event status);
-//
+    void removeStatusCallback(const std::vector<int> &ids,
+            email_noti_on_storage_event status);
+
     void loadMessageBody(MessageBodyCallbackData* callback);
 //    void loadMessageAttachment(MessageAttachmentCallbackData* callback);
 
@@ -106,25 +106,25 @@ private:
     typedef SendReqMap::iterator SendReqMapIterator;
     SendReqMapIterator getSendRequest(int mail_id);
     SendReqMap m_sendRequests;
-//    struct DeleteReq {
-//        MessagesCallbackUserData* callback;
-//        int messagesDeleted;
-//    };
-//    typedef std::vector<DeleteReq> DeleteReqVector;
-//    /**
-//     * Find first request containing at least one message id
-//     * @param ids
-//     * @return
-//     */
-//    DeleteReqVector::iterator getDeleteRequest(const std::vector<int> &ids);
-//    DeleteReqVector m_deleteRequests;
+    struct DeleteReq {
+        MessagesCallbackUserData* callback;
+        int messagesDeleted;
+    };
+    typedef std::vector<DeleteReq> DeleteReqVector;
+    /**
+     * Find first request containing at least one message id
+     * @param ids
+     * @return
+     */
+    DeleteReqVector::iterator getDeleteRequest(const std::vector<int> &ids);
+    DeleteReqVector m_deleteRequests;
 
     int m_slot_size;
 
     DBus::SyncProxyPtr m_proxy_sync;
     DBus::LoadBodyProxyPtr m_proxy_load_body;
 //    DBus::LoadAttachmentProxyPtr m_proxy_load_attachment;
-//    DBus::MessageProxyPtr m_proxy_messageStorage;
+    DBus::MessageProxyPtr m_proxy_messageStorage;
     DBus::SendProxyPtr m_proxy_send;
 
     std::mutex m_mutex;
index d4c1ee8542aca489b6b70d55dbc1538699f400f3..39be9438c469c54d7ea084256a92dd1be5cb5268 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "messaging_util.h"
 #include "message_callback_user_data.h"
+#include "messages_callback_user_data.h"
 
 namespace extension {
 namespace messaging {
@@ -27,7 +28,7 @@ public:
     virtual MessageType getMsgServiceType() const;
 
     virtual void addDraftMessage(MessageCallbackUserData* callback) = 0;
-    virtual void removeMessages() = 0;
+    virtual void removeMessages(MessagesCallbackUserData* callback) = 0;
     virtual void updateMessages() = 0;
     virtual void findMessages() = 0;
     virtual void findConversations() = 0;
index 2bc68aa28e9dd6c3ee931fbd7ab4b93bec3129e7..14f5e1570f25cf3ef4b70c72af38c190297d0246 100644 (file)
@@ -79,10 +79,33 @@ void MessageStorageEmail::addDraftMessage(MessageCallbackUserData* callback) {
     }
 }
 
-void MessageStorageEmail::removeMessages()
+static gboolean removeMessagesTask(void* data)
 {
     LoggerD("Entered");
-    //TODO add implementation
+
+    MessagesCallbackUserData *callback = static_cast<MessagesCallbackUserData*>(data);
+    EmailManager::getInstance().removeMessages(callback);
+
+    return FALSE;
+}
+
+void MessageStorageEmail::removeMessages(MessagesCallbackUserData* callback)
+{
+    LoggerD("Entered");
+
+    if (!callback) {
+        LoggerE("Callback is null");
+        throw common::UnknownException("Callback is null");
+    }
+
+    callback->setMessageServiceType(m_msg_type);
+
+    guint id = g_idle_add(removeMessagesTask, static_cast<void*>(callback));
+    if (!id) {
+        LoggerE("g_idle_add failed");
+        delete callback;
+        callback = NULL;
+    }
 }
 
 void MessageStorageEmail::updateMessages()
index 842180fb14e494e9af61824ff8e2270e9d5f50fc..0d6d04dacfd67526a3b6ed3c3d83ca6ca1bd190e 100644 (file)
@@ -16,7 +16,7 @@ public:
     virtual ~MessageStorageEmail();
 
     virtual void addDraftMessage(MessageCallbackUserData* callback);
-    virtual void removeMessages();
+    virtual void removeMessages(MessagesCallbackUserData* callback);
     virtual void updateMessages();
     virtual void findMessages();
     virtual void findConversations();
diff --git a/src/messaging/messages_callback_user_data.cc b/src/messaging/messages_callback_user_data.cc
new file mode 100644 (file)
index 0000000..ba7ea03
--- /dev/null
@@ -0,0 +1,77 @@
+
+// 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 "messages_callback_user_data.h"
+
+namespace extension {
+namespace messaging {
+
+MessagesCallbackUserData::MessagesCallbackUserData():
+        common::CallbackUserData(),
+        m_is_error(false),
+        m_service_type(MessageType::UNDEFINED)
+{
+}
+
+MessagesCallbackUserData::~MessagesCallbackUserData() {
+}
+
+void MessagesCallbackUserData::addMessage(std::shared_ptr<Message> msg)
+{
+    m_messages.push_back(msg);
+}
+
+std::vector<std::shared_ptr<Message>> MessagesCallbackUserData::getMessages() const
+{
+    return m_messages;
+}
+
+void MessagesCallbackUserData::setError(const std::string& err_name,
+        const std::string& err_message)
+{
+    // keep only first error in chain
+    if (!m_is_error) {
+        picojson::object& obj = m_json->get<picojson::object>();
+        obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR);
+        auto objData = picojson::object();
+
+        objData[JSON_ERROR_NAME] = picojson::value(err_name);
+        objData[JSON_ERROR_MESSAGE] = picojson::value(err_message);
+
+        obj[JSON_DATA] = picojson::value(objData);
+
+        m_is_error = true;
+        m_err_name = err_name;
+        m_err_message = err_message;
+    }
+}
+
+bool MessagesCallbackUserData::isError() const
+{
+    return m_is_error;
+}
+
+std::string MessagesCallbackUserData::getErrorName() const
+{
+    return m_err_name;
+}
+
+std::string MessagesCallbackUserData::getErrorMessage() const
+{
+    return m_err_message;
+}
+
+void MessagesCallbackUserData::setMessageServiceType(MessageType m_msg_type)
+{
+    m_service_type = m_msg_type;
+}
+
+MessageType MessagesCallbackUserData::getMessageServiceType() const
+{
+    return m_service_type;
+}
+
+}//messaging
+}//extension
diff --git a/src/messaging/messages_callback_user_data.h b/src/messaging/messages_callback_user_data.h
new file mode 100644 (file)
index 0000000..208a16e
--- /dev/null
@@ -0,0 +1,48 @@
+// 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_MESSAGES_CALLBACK_USER_DATA_H_
+#define MESSAGING_MESSAGES_CALLBACK_USER_DATA_H_
+
+#include "common/callback_user_data.h"
+#include "messaging_util.h"
+
+#include <memory>
+#include <string>
+
+namespace extension {
+namespace messaging {
+
+class Message;
+
+class MessagesCallbackUserData: public common::CallbackUserData {
+public:
+    MessagesCallbackUserData();
+    virtual ~MessagesCallbackUserData();
+
+    void addMessage(std::shared_ptr<Message> msg);
+    std::vector<std::shared_ptr<Message>> getMessages() const;
+
+    void setError(const std::string& err_name,
+            const std::string& err_message);
+    bool isError() const;
+    std::string getErrorName() const;
+    std::string getErrorMessage() const;
+
+    void setMessageServiceType(MessageType m_msg_type);
+    MessageType getMessageServiceType() const;
+
+private:
+    std::vector<std::shared_ptr<Message>> m_messages;
+    bool m_is_error;
+    std::string m_err_name;
+    std::string m_err_message;
+    MessageType m_service_type;
+};
+
+}//messaging
+}//extension
+
+#endif /* MESSAGING_MESSAGES_CALLBACK_USER_DATA_H_ */
+
diff --git a/src/messaging/messages_change_callback.cc b/src/messaging/messages_change_callback.cc
new file mode 100644 (file)
index 0000000..2631320
--- /dev/null
@@ -0,0 +1,222 @@
+// 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 <JSUtil.h>
+
+#include "common/logger.h"
+#include "common/platform_exception.h"
+
+#include "messages_change_callback.h"
+//#include "JSMessage.h"
+//#include "AbstractFilter.h"
+//#include "MessagingUtil.h"
+
+namespace extension {
+namespace messaging {
+
+namespace {
+
+std::string limitedString(const std::string& src,
+                          const size_t max_len = 40)
+{
+    if(src.length() > max_len) {
+        return src.substr(0,max_len);
+    } else {
+        return src;
+    }
+}
+
+} //Anonymous namespace
+
+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,*/
+        int service_id,
+        MessageType service_type) :
+        /*m_callback_data(global_ctx),*/
+        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);
+}
+
+MessagesChangeCallback::~MessagesChangeCallback()
+{
+    LOGD("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;
+ *    }
+ *}
+ */
+
+/*
+ *void MessagesChangeCallback::added(const MessagePtrVector& msgs)
+ *{
+ *    LOGD("Entered num messages: %d", msgs.size());
+ *    if (!m_is_act) {
+ *        return;
+ *    }
+ *    JSContextRef ctx = m_callback_data.getContext();
+ *    CHECK_CURRENT_CONTEXT_ALIVE(ctx)
+ *    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 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());
+ *    if (!m_is_act) {
+ *        return;
+ *    }
+ *    JSContextRef ctx = m_callback_data.getContext();
+ *    CHECK_CURRENT_CONTEXT_ALIVE(ctx)
+ *    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 updated messages", MESSAGESUPDATED,
+ *        filtered_msgs.size());
+ *    m_callback_data.invokeCallback(MESSAGESUPDATED, js_obj);
+ *}
+ */
+
+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);
+ */
+}
+
+/*
+ *void MessagesChangeCallback::setFilter(AbstractFilterPtr filter)
+ *{
+ *    m_filter = filter;
+ *}
+ */
+
+/*
+ *AbstractFilterPtr MessagesChangeCallback::getFilter() const
+ *{
+ *    return m_filter;
+ *}
+ */
+
+int MessagesChangeCallback::getServiceId() const
+{
+    return m_service_id;
+}
+
+MessageType MessagesChangeCallback::getServiceType() const
+{
+    return m_msg_type;
+}
+
+void MessagesChangeCallback::setActive(bool act) {
+    m_is_act = act;
+}
+
+bool MessagesChangeCallback::isActive() {
+    return m_is_act;
+}
+
+void MessagesChangeCallback::setItems(MessagePtrVector& items)
+{
+    m_items = items;
+}
+MessagePtrVector MessagesChangeCallback::getItems()
+{
+    return m_items;
+}
+
+
+} //namespace messaging
+} //namespace extension
diff --git a/src/messaging/messages_change_callback.h b/src/messaging/messages_change_callback.h
new file mode 100644 (file)
index 0000000..f4d44c3
--- /dev/null
@@ -0,0 +1,65 @@
+// 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 __TIZEN_MESSAGES_CHANGE_CALLBACK_H__
+#define __TIZEN_MESSAGES_CHANGE_CALLBACK_H__
+
+//#include <JavaScriptCore/JavaScript.h>
+
+//#include <MultiCallbackUserData.h>
+
+//#include <AbstractFilter.h>
+
+#include "message.h"
+#include "messaging_util.h"
+
+namespace extension {
+namespace messaging {
+
+extern const char* MESSAGESADDED;
+extern const char* MESSAGESUPDATED;
+extern const char* MESSAGESREMOVED;
+
+class MessagesChangeCallback {
+public:
+    MessagesChangeCallback(
+            int service_id,
+            MessageType service_type);
+    virtual ~MessagesChangeCallback();
+
+    //void added(const MessagePtrVector& messages);
+    //void updated(const MessagePtrVector& messages);
+    void removed(const MessagePtrVector& messages);
+
+    //void setFilter(DeviceAPI::Tizen::AbstractFilterPtr filter);
+    //DeviceAPI::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);
+     */
+
+    void setActive(bool act);
+    bool isActive();
+
+    void setItems(MessagePtrVector& items);
+    MessagePtrVector getItems();
+private:
+    //Common::MultiCallbackUserData m_callback_data;
+    //DeviceAPI::Tizen::AbstractFilterPtr m_filter;
+    int m_service_id;
+    MessageType m_msg_type;
+    bool m_is_act;
+    MessagePtrVector m_items;
+};
+
+} //namespace messaging
+} //namespace extension
+
+
+#endif // __TIZEN_MESSAGES_CHANGE_CALLBACK_H__
index ab04c0d82b8bf5487fe6c118970e9e141b9bc3fa..563951f045f1ae397c5593bddc93e7a133dcc9cf 100644 (file)
@@ -62,8 +62,8 @@
         #'DBus/LoadAttachmentProxy.h',
         'DBus/LoadBodyProxy.cpp',
         'DBus/LoadBodyProxy.h',
-        #'DBus/MessageProxy.cpp',
-        #'DBus/MessageProxy.h',
+        'DBus/MessageProxy.cpp',
+        'DBus/MessageProxy.h',
         'DBus/Proxy.cpp',
         'DBus/Proxy.h',
         'DBus/SendProxy.cpp',
         'MsgCommon/CompositeFilter.h',
         'MsgCommon/FilterIterator.cpp',
         'MsgCommon/FilterIterator.h',
+        'message_callback_user_data.cc',
+        'message_callback_user_data.h',
+        'messages_callback_user_data.cc',
+        'messages_callback_user_data.h',
+        'change_listener_container.cc',
+        'change_listener_container.h',
+        'messages_change_callback.cc',
+        'messages_change_callback.h'
       ],
       'includes': [
         '../common/pkg-config.gypi',
index a128f07e817511370521d37b61a519d653f3cc8b..731a6579cd1c7cbda2891b39373b79b78a9fae09 100644 (file)
@@ -817,10 +817,14 @@ MessageStorage.prototype.removeMessages = function () {
         {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
     ]);
 
+    var self = this;
+
     bridge.async({
         cmd: 'MessageStorage_removeMessages',
         args: {
-            messages: args.messages
+            messages: args.messages,
+            serviceId: self.service.id,
+            type: self.service.type
         }
     }).then({
         success: function () {
index 560f4c9d1a4b5b52e67421117229d8f87a0e414e..927b29489232f6ff539cbefbfe08a09d3fc761e8 100644 (file)
@@ -352,6 +352,27 @@ void MessagingInstance::MessageStorageRemoveMessages(const picojson::value& args
         picojson::object& out)
 {
     LoggerD("Entered");
+    picojson::object data = args.get(JSON_DATA).get<picojson::object>();
+    picojson::array messages = data.at(REMOVE_MESSAGES_ARGS_MESSAGES).get<picojson::array>();
+    const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
+
+    MessagesCallbackUserData* callback = new MessagesCallbackUserData();
+
+    auto each = [callback] (picojson::value& v)->void {
+        callback->addMessage(MessagingUtil::jsonToMessage(v));
+    };
+
+    for_each(messages.begin(), messages.end(), each);
+
+    auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
+    picojson::object& obj = json->get<picojson::object>();
+    obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
+    callback->setJson(json);
+
+    int serviceId = static_cast<int>(data.at(FUNCTIONS_HIDDEN_ARGS_SERVICE_ID).get<double>());
+    auto service = MessagingManager::getInstance().getMessageServiceEmail(serviceId);
+
+    service->getMsgStorage()->removeMessages(callback);
 }
 
 void MessagingInstance::MessageStorageUpdateMessages(const picojson::value& args,