[Messaging] add updateMessages method
authorRobert Karolak <r.karolak@samsung.com>
Fri, 19 Dec 2014 21:16:38 +0000 (22:16 +0100)
committerJerzy Pabich <j.pabich@samsung.com>
Wed, 24 Dec 2014 08:30:05 +0000 (09:30 +0100)
[Verification] Code compiles without errors.
Message update properly during test in node console.

Change-Id: Icda70a06f2e1e0ac96bb02b39848d4d40e2b754a
Signed-off-by: Robert Karolak <r.karolak@samsung.com>
12 files changed:
src/messaging/DBus/MessageProxy.cpp
src/messaging/email_manager.cc
src/messaging/email_manager.h
src/messaging/message_service.cc
src/messaging/message_storage.h
src/messaging/message_storage_email.cc
src/messaging/message_storage_email.h
src/messaging/messages_callback_user_data.cc
src/messaging/messages_callback_user_data.h
src/messaging/messaging_api.js
src/messaging/messaging_instance.cc
src/messaging/messaging_util.cc

index 85feaa4..893881d 100644 (file)
@@ -134,35 +134,32 @@ 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
-    //ConversationPtr conv = MessageConversation::convertEmailConversationToObject(
-            //thread_id);
+//    TODO uncomment when conversations will be available
+//    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);
-    // TODO
-    //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);
-            // TODO
-            //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);
-            //}
+//            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);
+//            }
             break;
         case NOTI_MAIL_UPDATE:
             ChangeListenerContainer::getInstance().callMessageUpdated(eventMsg);
-            // TODO
-            //ChangeListenerContainer::getInstance().callConversationUpdated(eventConv);
+//            ChangeListenerContainer::getInstance().callConversationUpdated(eventConv);
             break;
         default:
             LoggerW("Unknown event type: %d", event);
@@ -170,8 +167,7 @@ void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id,
 
     }
     delete eventMsg;
-    // TODO
-    //delete eventConv;
+//    delete eventConv;
 
     EmailManager::getInstance().freeMessage(mail_data);
 }
@@ -232,9 +228,8 @@ 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
+    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);
  *
@@ -250,9 +245,8 @@ void MessageProxy::handleThreadRemoveEvent(int account_id, int thread_id)
 
 void MessageProxy::handleMailboxEvent(int account_id, int mailbox_id, int event)
 {
-/*
- *    LoggerD("Enter");
- *
+    LoggerD("Enter");
+ /*
  *    EventFolders* eventFolder = new EventFolders();
  *    eventFolder->service_type = MessageType::EMAIL;
  *    eventFolder->service_id = account_id;
index 1786234..0bf8e5e 100644 (file)
@@ -942,105 +942,96 @@ void EmailManager::removeMessages(MessagesCallbackUserData* callback)
     }
 }
 
-//void EmailManager::updateMessages(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 updating message");
-//            }
-//        }
-//        for (auto it = messages.begin() ; it != messages.end(); ++it) {
-//
-//            mail = Message::convertPlatformEmail((*it));
-//
-//            if((*it)->getHasAttachment())
-//            {
-//                LoggerD("Message has attachments. Workaround need to be used.");
-//                //Update of mail on server using function email_update_mail() is not possible.
-//                //Attachment is updated only locally (can't be later loaded from server),
-//                //so use of workaround is needed:
-//                //1. add new mail
-//                //2. delete old mail
-//
-//                //adding message again after changes
-//                addDraftMessagePlatform(mail->account_id, (*it));
-//                LoggerD("mail added - new id = [%d]\n", (*it)->getId());
-//
-//                //deleting old mail
-//                LoggerD("mail deleted = [%d]\n", mail->mail_id);
-//                error = email_delete_mail(mail->mailbox_id,&mail->mail_id,1,1);
-//                if (EMAIL_ERROR_NONE != error) {
-//                    email_free_mail_data(&mail, 1);
-//                    LoggerE("Error while deleting old mail on update: %d", error);
-//                    throw Common::UnknownException("Error while deleting old mail on update");
-//                }
-//            } else {
-//                LoggerD("There are no attachments, updating only email data.");
-//                error = email_update_mail(mail, NULL, 0, NULL, 0);
-//                if (EMAIL_ERROR_NONE != error) {
-//                    email_free_mail_data(&mail, 1);
-//                    LoggerE("Error while updating mail");
-//                    throw UnknownException("Error while updating mail");
-//                }
-//            }
-//
-//            email_free_mail_data(&mail, 1);
-//        }
-//
-//    } catch (const BasePlatformException& err) {
-//        LoggerE("%s (%s)", (err.getName()).c_str(), (err.getMessage()).c_str());
-//        callback->setError(err.getName(), err.getMessage());
-//    } catch (...) {
-//        LoggerE("Messages update failed");
-//        callback->setError(JSWebAPIErrorFactory::UNKNOWN_ERROR, "Messages update failed");
-//    }
-//
-//    //Complete task
-//    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 updateEmail callback: %s (%s)",
-//                (err.getName()).c_str(), (err.getMessage()).c_str());
-//    } catch (...) {
-//        LoggerE("Unknown error when calling updateEmail callback.");
-//    }
-//
-//    delete callback;
-//    callback = NULL;
-//}
+void EmailManager::updateMessages(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 updating message");
+            }
+        }
+        for (auto it = messages.begin() ; it != messages.end(); ++it) {
+
+            mail = Message::convertPlatformEmail((*it));
+
+            if((*it)->getHasAttachment())
+            {
+                LoggerD("Message has attachments. Workaround need to be used.");
+                //Update of mail on server using function email_update_mail() is not possible.
+                //Attachment is updated only locally (can't be later loaded from server),
+                //so use of workaround is needed:
+                //1. add new mail
+                //2. delete old mail
+
+                //adding message again after changes
+                addDraftMessagePlatform(mail->account_id, (*it));
+                LoggerD("mail added - new id = [%d]\n", (*it)->getId());
+
+                //deleting old mail
+                LoggerD("mail deleted = [%d]\n", mail->mail_id);
+                error = email_delete_mail(mail->mailbox_id,&mail->mail_id,1,1);
+                if (EMAIL_ERROR_NONE != error) {
+                    email_free_mail_data(&mail, 1);
+                    LoggerE("Error while deleting old mail on update: %d", error);
+                    throw UnknownException("Error while deleting old mail on update");
+                }
+            } else {
+                LoggerD("There are no attachments, updating only email data.");
+                error = email_update_mail(mail, NULL, 0, NULL, 0);
+                if (EMAIL_ERROR_NONE != error) {
+                    email_free_mail_data(&mail, 1);
+                    LoggerE("Error while updating mail");
+                    throw UnknownException("Error while updating mail");
+                }
+            }
+
+            email_free_mail_data(&mail, 1);
+        }
+
+    } catch (const PlatformException& err) {
+        LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str());
+        callback->setError(err.name(), err.message());
+    } catch (...) {
+        LoggerE("Messages update failed");
+        UnknownException ex("Messages update failed");
+        callback->setError(ex.name(), ex.message());
+    }
+
+    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 updateEmail callback: %s (%s)",
+                (err.name()).c_str(), (err.message()).c_str());
+    } catch (...) {
+        LoggerE("Unknown error when calling updateEmail callback.");
+    }
+
+    delete callback;
+    callback = NULL;
+}
 
 void EmailManager::findMessages(FindMsgCallbackUserData* callback)
 {
index 5928fde..a6b54b5 100644 (file)
@@ -61,7 +61,7 @@ public:
 
     void addDraftMessage(MessageCallbackUserData* callback);
     void removeMessages(MessagesCallbackUserData* callback);
-//    void updateMessages(MessagesCallbackUserData* callback);
+    void updateMessages(MessagesCallbackUserData* callback);
     void findMessages(FindMsgCallbackUserData* callback);
 //    void findConversations(ConversationCallbackData* callback);
 //    void findFolders(FoldersCallbackData* callback);
index fa81163..7449789 100644 (file)
@@ -65,6 +65,16 @@ void MessageRecipientsCallbackData::setError(const std::string& err_name,
 {
     // 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;
index 42fce1d..ba5c7b4 100644 (file)
@@ -31,7 +31,7 @@ public:
 
     virtual void addDraftMessage(MessageCallbackUserData* callback) = 0;
     virtual void removeMessages(MessagesCallbackUserData* callback) = 0;
-    virtual void updateMessages() = 0;
+    virtual void updateMessages(MessagesCallbackUserData* callback) = 0;
     virtual void findMessages() = 0;
     virtual void findConversations() = 0;
     virtual void removeConversations() = 0;
index 14f5e15..37816b4 100644 (file)
@@ -108,10 +108,32 @@ void MessageStorageEmail::removeMessages(MessagesCallbackUserData* callback)
     }
 }
 
-void MessageStorageEmail::updateMessages()
+static gboolean updateMessagesTask(void* data)
 {
     LoggerD("Entered");
-    //TODO add implementation
+
+    MessagesCallbackUserData *callback = static_cast<MessagesCallbackUserData*>(data);
+    EmailManager::getInstance().updateMessages(callback);
+
+    return FALSE;
+}
+
+void MessageStorageEmail::updateMessages(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(updateMessagesTask, static_cast<void*>(callback));
+    if (!id) {
+        LoggerE("g_idle_add failed");
+        delete callback;
+        callback = NULL;
+    }
 }
 
 void MessageStorageEmail::findMessages()
index 0d6d04d..46af24d 100644 (file)
@@ -17,7 +17,7 @@ public:
 
     virtual void addDraftMessage(MessageCallbackUserData* callback);
     virtual void removeMessages(MessagesCallbackUserData* callback);
-    virtual void updateMessages();
+    virtual void updateMessages(MessagesCallbackUserData* callback);
     virtual void findMessages();
     virtual void findConversations();
     virtual void removeConversations();
index b45c795..a541c76 100644 (file)
@@ -1,4 +1,3 @@
-
 // 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.
index 4d330dc..b39806f 100644 (file)
@@ -6,11 +6,12 @@
 #define MESSAGING_MESSAGES_CALLBACK_USER_DATA_H_
 
 #include "common/callback_user_data.h"
-#include "messaging_util.h"
 
 #include <memory>
 #include <string>
 
+#include "messaging_util.h"
+
 namespace extension {
 namespace messaging {
 
@@ -46,4 +47,3 @@ private:
 }//extension
 
 #endif /* MESSAGING_MESSAGES_CALLBACK_USER_DATA_H_ */
-
index db7ade8..c167d66 100644 (file)
@@ -850,10 +850,13 @@ MessageStorage.prototype.updateMessages = function () {
         {name: 'errorCallback', type: types_.FUNCTION, optional: true, nullable: true}
     ]);
 
+    var self = this;
+
     bridge.async({
         cmd: 'MessageStorage_updateMessages',
         args: {
-            messages: args.messages
+            messages: args.messages,
+            serviceId: self.service.id
         }
     }).then({
         success: function () {
index 9250823..355dac8 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "MsgCommon/AbstractFilter.h"
 #include "messages_change_callback.h"
+#include "messages_callback_user_data.h"
 #include "messaging_manager.h"
 #include "messaging_util.h"
 #include "message_storage.h"
@@ -117,9 +118,11 @@ MessagingInstance::MessagingInstance()
       REGISTER_ASYNC(FUN_MESSAGE_STORAGE_ADD_DRAFT_MESSAGE, MessageStorageAddDraft);
       REGISTER_ASYNC(FUN_MESSAGE_STORAGE_FIND_MESSAGES, MessageStorageFindMessages);
       REGISTER_ASYNC(FUN_MESSAGE_STORAGE_REMOVE_MESSAGES, MessageStorageRemoveMessages);
+      REGISTER_ASYNC(FUN_MESSAGE_STORAGE_UPDATE_MESSAGES, MessageStorageUpdateMessages);
       REGISTER_ASYNC(FUN_MESSAGE_STORAGE_FIND_CONVERSATIONS, MessageStorageFindConversations);
       REGISTER_ASYNC(FUN_MESSAGE_STORAGE_REMOVE_CONVERSATIONS, MessageStorageRemoveConversations);
       REGISTER_ASYNC(FUN_MESSAGE_STORAGE_FIND_FOLDERS, MessageStorageFindFolders);
+      REGISTER_ASYNC(FUN_MESSAGE_STORAGE_ADD_MESSAGES_CHANGE_LISTENER, MessageStorageAddMessagesChangeListener);
       REGISTER_ASYNC(FUN_MESSAGE_STORAGE_ADD_CONVERSATIONS_CHANGE_LISTENER, MessageStorageAddConversationsChangeListener);
       REGISTER_ASYNC(FUN_MESSAGE_STORAGE_ADD_FOLDER_CHANGE_LISTENER, MessageStorageAddFolderChangeListener);
     #undef REGISTER_ASYNC
@@ -167,6 +170,7 @@ void MessagingInstance::GetMessageServices(const picojson::value& args,
              msg.attachments = [new tizen.MessageAttachment("images/myimage.png", "image/png")];
              services[0].sendMessage(msg, function(data){
                  console.log("Send email success");
+                 console.dir(data);
              }, function(){
                  console.log("Send email failed");
              });
@@ -381,6 +385,29 @@ void MessagingInstance::MessageStorageUpdateMessages(const picojson::value& args
         picojson::object& out)
 {
     LoggerD("Entered");
+
+    picojson::object data = args.get(JSON_DATA).get<picojson::object>();
+    picojson::value pico_messages = data.at(UPDATE_MESSAGES_ARGS_MESSAGES);
+    auto pico_array = pico_messages.get<picojson::array>();
+    const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
+
+    auto callback = new MessagesCallbackUserData();
+
+    std::vector<std::shared_ptr<Message>> messages;
+    std::for_each(pico_array.begin(), pico_array.end(), [&callback](picojson::value& v)->void {
+       callback->addMessage(MessagingUtil::jsonToMessage(v));
+    });
+
+    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>
+            (MessagingUtil::getValueFromJSONObject<double>(data,FUNCTIONS_HIDDEN_ARGS_SERVICE_ID));
+    auto service = MessagingManager::getInstance().getMessageServiceEmail(serviceId);
+
+    service->getMsgStorage()->updateMessages(callback);
 }
 
 void MessagingInstance::MessageStorageFindConversations(const picojson::value& args,
index 5dc530a..82f31e0 100644 (file)
@@ -336,7 +336,6 @@ std::shared_ptr<Message> MessagingUtil::jsonToMessage(const picojson::value& jso
             } else {
                 message = Message::convertPlatformEmailToObject(*mail);
                 email_free_mail_data(&mail,1);
-                return message;
             }
         } else {
             message = std::shared_ptr<Message>(new MessageEmail());