Merge "[Sensor] Fix for HRM_RAW sensor" into tizen_4.0
[platform/core/api/webapi-plugins.git] / src / messaging / messaging_instance.cc
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16
17 #include "messaging_instance.h"
18
19 #include <system_info.h>
20 #include <sstream>
21 #include <stdexcept>
22
23 #include "common/logger.h"
24 #include "common/tools.h"
25
26 #include "MsgCommon/AbstractFilter.h"
27 #include "conversations_change_callback.h"
28 #include "email_manager.h"
29 #include "find_msg_callback_user_data.h"
30 #include "folders_callback_data.h"
31 #include "folders_change_callback.h"
32 #include "message.h"
33 #include "message_storage.h"
34 #include "messages_callback_user_data.h"
35 #include "messages_change_callback.h"
36 #include "messaging_manager.h"
37 #include "messaging_util.h"
38 #include "short_message_manager.h"
39
40 using common::ErrorCode;
41 using common::TypeMismatchException;
42 using common::PlatformResult;
43
44 namespace extension {
45 namespace messaging {
46
47 namespace {
48 const char* FUN_GET_MESSAGE_SERVICES = "Messaging_getMessageServices";
49 const char* GET_MESSAGE_SERVICES_ARGS_MESSAGE_SERVICE_TYPE = "messageServiceType";
50
51 const char* FUN_MESSAGE_SERVICE_SEND_MESSAGE = "MessageService_sendMessage";
52 const char* SEND_MESSAGE_ARGS_MESSAGE = "message";
53 const char* SEND_MESSAGE_ARGS_SIMINDEX = "simIndex";
54
55 const char* FUN_MESSAGE_SERVICE_LOAD_MESSAGE_BODY = "MessageService_loadMessageBody";
56
57 const char* FUN_MESSAGE_SERVICE_LOAD_MESSAGE_ATTACHMENT = "MessageService_loadMessageAttachment";
58 const char* LOAD_MESSAGE_ATTACHMENT_ARGS_ATTACHMENT = "attachment";
59
60 const char* FUN_MESSAGE_SERVICE_SYNC = "MessageService_sync";
61 const char* SYNC_ARGS_ID = "id";
62 const char* SYNC_ARGS_LIMIT = "limit";
63
64 const char* FUN_MESSAGE_SERVICE_SYNC_FOLDER = "MessageService_syncFolder";
65 const char* SYNC_FOLDER_ARGS_ID = "id";
66 const char* SYNC_FOLDER_ARGS_FOLDER = "folder";
67 const char* SYNC_FOLDER_ARGS_LIMIT = "limit";
68
69 const char* FUN_MESSAGE_SERVICE_STOP_SYNC = "MessageService_stopSync";
70 const char* STOP_SYNC_ARGS_ID = "id";
71 const char* STOP_SYNC_ARGS_OPID = "opId";
72
73 const char* FUN_MESSAGE_STORAGE_ADD_DRAFT_MESSAGE = "MessageStorage_addDraftMessage";
74 const char* ADD_DRAFT_MESSAGE_ARGS_MESSAGE = "message";
75
76 const char* FUN_MESSAGE_STORAGE_FIND_MESSAGES = "MessageStorage_findMessages";
77
78 const char* FUN_MESSAGE_STORAGE_REMOVE_MESSAGES = "MessageStorage_removeMessages";
79 const char* REMOVE_MESSAGES_ARGS_MESSAGES = "messages";
80
81 const char* FUN_MESSAGE_STORAGE_UPDATE_MESSAGES = "MessageStorage_updateMessages";
82 const char* UPDATE_MESSAGES_ARGS_MESSAGES = "messages";
83
84 const char* FUN_MESSAGE_STORAGE_FIND_CONVERSATIONS = "MessageStorage_findConversations";
85 const char* FIND_CONVERSATIONS_ARGS_LIMIT = "limit";
86 const char* FIND_CONVERSATIONS_ARGS_OFFSET = "offset";
87
88 const char* FUN_MESSAGE_STORAGE_REMOVE_CONVERSATIONS = "MessageStorage_removeConversations";
89 const char* REMOVE_CONVERSATIONS_ARGS_CONVERSATIONS = "conversations";
90
91 const char* FUN_MESSAGE_STORAGE_FIND_FOLDERS = "MessageStorage_findFolders";
92 const char* FIND_FOLDERS_ARGS_LIMIT = "limit";
93 const char* FIND_FOLDERS_ARGS_OFFSET = "offset";
94
95 const char* FUN_MESSAGE_STORAGE_ADD_MESSAGES_CHANGE_LISTENER =
96     "MessageStorage_addMessagesChangeListener";
97
98 const char* FUN_MESSAGE_STORAGE_ADD_CONVERSATIONS_CHANGE_LISTENER =
99     "MessageStorage_addConversationsChangeListener";
100
101 const char* FUN_MESSAGE_STORAGE_ADD_FOLDER_CHANGE_LISTENER =
102     "MessageStorage_addFoldersChangeListener";
103
104 const char* FUN_MESSAGE_STORAGE_REMOVE_CHANGE_LISTENER = "MessageStorage_removeChangeListener";
105 const char* REMOVE_CHANGE_LISTENER_ARGS_WATCHID = "watchId";
106
107 const char* FUNCTIONS_HIDDEN_ARGS_SERVICE_ID = "serviceId";
108 const char* FUN_MESSAGE_GET_MESSAGE_STATUS = "Message_messageStatus";
109 const char* FUN_MESSAGE_MESSAGING_EMAIL = "messaging.email";
110
111 auto getServiceIdFromJSON = [](picojson::object& data) -> int {
112   std::string serviceStrId;
113   try {
114     serviceStrId =
115         MessagingUtil::getValueFromJSONObject<std::string>(data, FUNCTIONS_HIDDEN_ARGS_SERVICE_ID);
116     return std::stoi(serviceStrId);
117   } catch (...) {
118     return -1;
119   }
120 };
121
122 const std::string kPrivilegeMessagingRead = "http://tizen.org/privilege/messaging.read";
123 const std::string kPrivilegeMessagingWrite = "http://tizen.org/privilege/messaging.write";
124
125 const long kDumbCallbackId = -1;
126 }
127
128 MessagingInstance::MessagingInstance() : manager_(*this), queue_(*this) {
129   ScopeLogger();
130   using std::placeholders::_1;
131   using std::placeholders::_2;
132 #define REGISTER_ASYNC(c, x) RegisterSyncHandler(c, std::bind(&MessagingInstance::x, this, _1, _2));
133   REGISTER_ASYNC(FUN_GET_MESSAGE_SERVICES, GetMessageServices);
134   REGISTER_ASYNC(FUN_MESSAGE_SERVICE_SEND_MESSAGE, MessageServiceSendMessage);
135   REGISTER_ASYNC(FUN_MESSAGE_SERVICE_LOAD_MESSAGE_BODY, MessageServiceLoadMessageBody);
136   REGISTER_ASYNC(FUN_MESSAGE_SERVICE_LOAD_MESSAGE_ATTACHMENT, MessageServiceLoadMessageAttachment);
137   REGISTER_ASYNC(FUN_MESSAGE_STORAGE_ADD_DRAFT_MESSAGE, MessageStorageAddDraft);
138   REGISTER_ASYNC(FUN_MESSAGE_STORAGE_FIND_MESSAGES, MessageStorageFindMessages);
139   REGISTER_ASYNC(FUN_MESSAGE_STORAGE_REMOVE_MESSAGES, MessageStorageRemoveMessages);
140   REGISTER_ASYNC(FUN_MESSAGE_STORAGE_UPDATE_MESSAGES, MessageStorageUpdateMessages);
141   REGISTER_ASYNC(FUN_MESSAGE_STORAGE_FIND_CONVERSATIONS, MessageStorageFindConversations);
142   REGISTER_ASYNC(FUN_MESSAGE_STORAGE_REMOVE_CONVERSATIONS, MessageStorageRemoveConversations);
143   REGISTER_ASYNC(FUN_MESSAGE_STORAGE_FIND_FOLDERS, MessageStorageFindFolders);
144 #undef REGISTER_ASYNC
145 #define REGISTER_SYNC(c, x) RegisterSyncHandler(c, std::bind(&MessagingInstance::x, this, _1, _2));
146   REGISTER_SYNC(FUN_MESSAGE_SERVICE_SYNC, MessageServiceSync);
147   REGISTER_SYNC(FUN_MESSAGE_SERVICE_STOP_SYNC, MessageServiceStopSync);
148   REGISTER_SYNC(FUN_MESSAGE_SERVICE_SYNC_FOLDER, MessageServiceSyncFolder);
149   REGISTER_SYNC(FUN_MESSAGE_STORAGE_ADD_MESSAGES_CHANGE_LISTENER,
150                 MessageStorageAddMessagesChangeListener);
151   REGISTER_SYNC(FUN_MESSAGE_STORAGE_ADD_CONVERSATIONS_CHANGE_LISTENER,
152                 MessageStorageAddConversationsChangeListener);
153   REGISTER_SYNC(FUN_MESSAGE_STORAGE_ADD_FOLDER_CHANGE_LISTENER,
154                 MessageStorageAddFolderChangeListener);
155   REGISTER_SYNC(FUN_MESSAGE_STORAGE_REMOVE_CHANGE_LISTENER, MessageStorageRemoveChangeListener);
156   REGISTER_SYNC(FUN_MESSAGE_GET_MESSAGE_STATUS, MessageGetMessageStatus);
157 #undef REGISTER_SYNC
158 }
159
160 MessagingInstance::~MessagingInstance() {
161   ScopeLogger();
162 }
163
164 #define POST_AND_RETURN(ret, json, obj)                                            \
165   LogAndReportError(ret, &obj);                                                    \
166   queue_.addAndResolve(obj.at(JSON_CALLBACK_ID).get<double>(), PostPriority::HIGH, \
167                        json->serialize());                                         \
168   return;
169
170 #define CHECK_EXIST(args, name, out)                                                \
171   if (!args.contains(name)) {                                                       \
172     std::string message = std::string(name) + " is required argument";              \
173     LogAndReportError(PlatformResult(ErrorCode::TYPE_MISMATCH_ERR, message), &out); \
174     return;                                                                         \
175   }
176
177 void MessagingInstance::GetMessageServices(const picojson::value& args, picojson::object& out) {
178   ScopeLogger();
179
180   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
181
182   picojson::value serviceTag =
183       args.get<picojson::object>().at(GET_MESSAGE_SERVICES_ARGS_MESSAGE_SERVICE_TYPE);
184   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
185   // above values should be validated in js
186   manager_.getMessageServices(serviceTag.to_str(), callbackId);
187 }
188
189 void MessagingInstance::MessageServiceSendMessage(const picojson::value& args,
190                                                   picojson::object& out) {
191   ScopeLogger();
192
193   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
194   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
195
196   picojson::object data = args.get<picojson::object>();
197   picojson::value v_message = data.at(SEND_MESSAGE_ARGS_MESSAGE);
198   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
199
200   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
201   picojson::object& obj = json->get<picojson::object>();
202   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
203
204   std::shared_ptr<Message> message;
205   PlatformResult ret = MessagingUtil::jsonToMessage(v_message, &message);
206   if (ret.IsError()) {
207     POST_AND_RETURN(ret, json, obj)
208   }
209
210   MessageRecipientsCallbackData* callback = new MessageRecipientsCallbackData(queue_, callbackId);
211   long simIndex = 0;
212   int serviceId = 0;
213
214   callback->setMessage(message);
215   serviceId = getServiceIdFromJSON(data);
216   callback->setAccountId(serviceId);
217   simIndex = static_cast<long>(
218       MessagingUtil::getValueFromJSONObject<double>(data, SEND_MESSAGE_ARGS_SIMINDEX));
219
220   bool cell_support = false;
221   system_info_get_platform_bool("http://tizen.org/feature/network.telephony", &cell_support);
222   if (cell_support) {
223     LoggerD("cell_support is true");
224     if (!callback->setSimIndex(simIndex)) {
225       delete callback;
226       callback = nullptr;
227       POST_AND_RETURN(PlatformResult(ErrorCode::UNKNOWN_ERR, "set sim index failed"), json, obj)
228     }
229   } else {
230     LoggerD("cell_support is false");
231   }
232
233   callback->AddToQueue();
234   auto service = manager_.getMessageService(serviceId);
235
236   ret = service->sendMessage(callback);
237   if (!ret) {
238     POST_AND_RETURN(ret, json, obj)
239   }
240 }
241
242 void MessagingInstance::MessageServiceLoadMessageBody(const picojson::value& args,
243                                                       picojson::object& out) {
244   ScopeLogger();
245
246   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
247   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
248
249   picojson::object data = args.get<picojson::object>();
250
251   picojson::value json_message = data.at(ADD_DRAFT_MESSAGE_ARGS_MESSAGE);
252   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
253
254   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
255   picojson::object& obj = json->get<picojson::object>();
256   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
257
258   std::shared_ptr<Message> message;
259   PlatformResult ret = MessagingUtil::jsonToMessage(json_message, &message);
260   if (ret.IsError()) {
261     POST_AND_RETURN(ret, json, obj)
262   }
263
264   MessageBodyCallbackData* callback = new MessageBodyCallbackData(queue_, callbackId);
265
266   callback->setMessage(message);
267
268   callback->AddToQueue();
269   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
270   ret = service->loadMessageBody(callback);
271   if (ret.IsError()) {
272     POST_AND_RETURN(ret, json, obj)
273   }
274 }
275
276 void MessagingInstance::MessageServiceLoadMessageAttachment(const picojson::value& args,
277                                                             picojson::object& out) {
278   ScopeLogger();
279
280   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
281   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
282
283   picojson::object data = args.get<picojson::object>();
284   picojson::value attachment = data.at(LOAD_MESSAGE_ATTACHMENT_ARGS_ATTACHMENT);
285   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
286
287   MessageAttachmentCallbackData* callback = new MessageAttachmentCallbackData(queue_, callbackId);
288   callback->setMessageAttachment(MessagingUtil::jsonToMessageAttachment(attachment));
289
290   callback->AddToQueue();
291   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
292   const auto result = service->loadMessageAttachment(callback);
293   if (result.IsError()) {
294     auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
295     picojson::object& obj = json->get<picojson::object>();
296     obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
297     POST_AND_RETURN(result, json, obj)
298   }
299 }
300
301 void MessagingInstance::MessageServiceSync(const picojson::value& args, picojson::object& out) {
302   ScopeLogger();
303
304   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
305   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
306
307   picojson::object data = args.get<picojson::object>();
308   picojson::value v_id = data.at(SYNC_ARGS_ID);
309   picojson::value v_limit = data.at(SYNC_ARGS_LIMIT);
310   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
311
312   int id = -1;
313   try {
314     id = std::stoi(v_id.get<std::string>());
315   } catch (...) {
316     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out,
317                       ("Problem with MessageService"));
318     return;
319   }
320   long limit = 0;
321   if (v_limit.is<double>()) {
322     limit = static_cast<long>(v_limit.get<double>());
323   }
324
325   SyncCallbackData* callback = new SyncCallbackData(queue_, callbackId);
326   callback->setAccountId(id);
327   callback->setLimit(limit);
328
329   callback->AddToQueue();
330   long op_id = -1;
331
332   const auto result = manager_.getMessageService(id)->sync(callback, &op_id);
333
334   if (result) {
335     ReportSuccess(picojson::value(static_cast<double>(op_id)), out);
336   } else {
337     LogAndReportError(result, &out);
338   }
339 }
340
341 void MessagingInstance::MessageServiceSyncFolder(const picojson::value& args,
342                                                  picojson::object& out) {
343   ScopeLogger();
344
345   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
346   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
347
348   picojson::object data = args.get<picojson::object>();
349   picojson::value v_id = data.at(SYNC_FOLDER_ARGS_ID);
350   picojson::value v_folder = data.at(SYNC_FOLDER_ARGS_FOLDER);
351   picojson::value v_limit = data.at(SYNC_FOLDER_ARGS_LIMIT);
352   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
353
354   int id = -1;
355   try {
356     id = std::stoi(v_id.get<std::string>());
357   } catch (...) {
358     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out,
359                       ("Problem with MessageService"));
360     return;
361   }
362
363   long limit = 0;
364   if (v_limit.is<double>()) {
365     limit = static_cast<long>(v_limit.get<double>());
366   }
367
368   SyncFolderCallbackData* callback = new SyncFolderCallbackData(queue_, callbackId);
369   callback->setAccountId(id);
370   callback->setMessageFolder(MessagingUtil::jsonToMessageFolder(v_folder));
371   callback->setLimit(limit);
372
373   callback->AddToQueue();
374   long op_id = -1;
375
376   const auto result = manager_.getMessageService(id)->syncFolder(callback, &op_id);
377   if (result) {
378     ReportSuccess(picojson::value(static_cast<double>(op_id)), out);
379   } else {
380     LogAndReportError(result, &out);
381   }
382 }
383
384 void MessagingInstance::MessageServiceStopSync(const picojson::value& args, picojson::object& out) {
385   ScopeLogger();
386   CHECK_EXIST(args, STOP_SYNC_ARGS_OPID, out);
387
388   picojson::object data = args.get<picojson::object>();
389
390   if (data.find(STOP_SYNC_ARGS_ID) != data.end()) {
391     picojson::value v_id = data.at(STOP_SYNC_ARGS_ID);
392     picojson::value v_op_id = data.at(STOP_SYNC_ARGS_OPID);
393
394     int id = -1;
395     try {
396       id = std::stoi(v_id.get<std::string>());
397     } catch (...) {
398       LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out,
399                         ("Problem with MessageService"));
400       return;
401     }
402
403     long op_id = 0;
404     if (v_op_id.is<double>()) {
405       op_id = static_cast<long>(v_op_id.get<double>());
406     }
407
408     const auto result = manager_.getMessageService(id)->stopSync(op_id);
409
410     if (result) {
411       ReportSuccess(out);
412     } else {
413       LogAndReportError(result, &out);
414     }
415   } else {
416     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out, ("Unknown error"));
417   }
418 }
419
420 void MessagingInstance::MessageStorageAddDraft(const picojson::value& args, picojson::object& out) {
421   ScopeLogger();
422
423   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
424   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
425
426   picojson::object data = args.get<picojson::object>();
427   picojson::value v_message = data.at(ADD_DRAFT_MESSAGE_ARGS_MESSAGE);
428   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
429
430   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
431   picojson::object& obj = json->get<picojson::object>();
432   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
433
434   std::shared_ptr<Message> message;
435   PlatformResult ret = MessagingUtil::jsonToMessage(v_message, &message);
436   if (ret.IsError()) {
437     POST_AND_RETURN(ret, json, obj)
438   }
439
440   MessageCallbackUserData* callback = new MessageCallbackUserData(queue_, callbackId);
441   callback->setMessage(message);
442
443   int serviceId = getServiceIdFromJSON(data);
444   callback->setAccountId(serviceId);
445
446   callback->AddToQueue();
447   auto service = manager_.getMessageService(serviceId);
448   service->getMsgStorage()->addDraftMessage(callback);
449 }
450
451 void MessagingInstance::MessageStorageFindMessages(const picojson::value& args,
452                                                    picojson::object& out) {
453   ScopeLogger();
454
455   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
456   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
457
458   picojson::object data = args.get<picojson::object>();
459   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
460
461   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
462   picojson::object& obj = json->get<picojson::object>();
463   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
464
465   AbstractFilterPtr filter;
466   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
467   if (ret.IsError()) {
468     POST_AND_RETURN(ret, json, obj)
469   }
470   auto sortMode = MessagingUtil::jsonToSortMode(data);
471
472   long limit = static_cast<long>(
473       MessagingUtil::getValueFromJSONObject<double>(data, FIND_FOLDERS_ARGS_LIMIT));
474
475   long offset = static_cast<long>(
476       MessagingUtil::getValueFromJSONObject<double>(data, FIND_FOLDERS_ARGS_OFFSET));
477
478   int serviceId = getServiceIdFromJSON(data);
479   auto storage = manager_.getMessageService(serviceId)->getMsgStorage();
480
481   FindMsgCallbackUserData* callback = new FindMsgCallbackUserData(queue_, callbackId);
482   callback->setFilter(filter);
483   callback->setLimit(limit);
484   callback->setOffset(offset);
485   callback->setAccountId(serviceId);
486   callback->setSortMode(sortMode);
487
488   callback->AddToQueue();
489   storage->findMessages(callback);
490 }
491
492 void MessagingInstance::MessageStorageRemoveMessages(const picojson::value& args,
493                                                      picojson::object& out) {
494   ScopeLogger();
495
496   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
497   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
498
499   picojson::object data = args.get<picojson::object>();
500   picojson::array messages = data.at(REMOVE_MESSAGES_ARGS_MESSAGES).get<picojson::array>();
501   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
502
503   MessagesCallbackUserData* callback = new MessagesCallbackUserData(queue_, callbackId);
504
505   auto each = [callback](picojson::value& v) -> void {
506     std::shared_ptr<Message> message;
507     PlatformResult ret = MessagingUtil::jsonToMessage(v, &message);
508     if (ret.IsSuccess()) {
509       callback->addMessage(message);
510     }
511   };
512
513   for_each(messages.begin(), messages.end(), each);
514
515   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
516
517   callback->AddToQueue();
518   service->getMsgStorage()->removeMessages(callback);
519 }
520
521 void MessagingInstance::MessageStorageUpdateMessages(const picojson::value& args,
522                                                      picojson::object& out) {
523   ScopeLogger();
524
525   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
526   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
527
528   picojson::object data = args.get<picojson::object>();
529   picojson::value pico_messages = data.at(UPDATE_MESSAGES_ARGS_MESSAGES);
530   auto pico_array = pico_messages.get<picojson::array>();
531   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
532
533   auto callback = new MessagesCallbackUserData(queue_, callbackId);
534
535   std::for_each(pico_array.begin(), pico_array.end(), [&callback](picojson::value& v) -> void {
536     std::shared_ptr<Message> message;
537     PlatformResult ret = MessagingUtil::jsonToMessage(v, &message);
538     if (ret.IsSuccess()) {
539       callback->addMessage(message);
540     }
541   });
542
543   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
544
545   callback->AddToQueue();
546   service->getMsgStorage()->updateMessages(callback);
547 }
548
549 void MessagingInstance::MessageStorageFindConversations(const picojson::value& args,
550                                                         picojson::object& out) {
551   ScopeLogger();
552
553   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
554   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
555
556   picojson::object data = args.get<picojson::object>();
557   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
558
559   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
560   picojson::object& obj = json->get<picojson::object>();
561   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
562
563   AbstractFilterPtr filter;
564   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
565   if (ret.IsError()) {
566     POST_AND_RETURN(ret, json, obj)
567   }
568   auto sortMode = MessagingUtil::jsonToSortMode(data);
569   long limit = static_cast<long>(
570       MessagingUtil::getValueFromJSONObject<double>(data, FIND_CONVERSATIONS_ARGS_LIMIT));
571   long offset = static_cast<long>(
572       MessagingUtil::getValueFromJSONObject<double>(data, FIND_CONVERSATIONS_ARGS_OFFSET));
573
574   int serviceId = getServiceIdFromJSON(data);
575
576   ConversationCallbackData* callback = new ConversationCallbackData(queue_, callbackId);
577   callback->setFilter(filter);
578   callback->setLimit(limit);
579   callback->setOffset(offset);
580   callback->setAccountId(serviceId);
581   callback->setSortMode(sortMode);
582
583   callback->AddToQueue();
584   auto storage = manager_.getMessageService(serviceId)->getMsgStorage();
585   storage->findConversations(callback);
586 }
587
588 void MessagingInstance::MessageStorageRemoveConversations(const picojson::value& args,
589                                                           picojson::object& out) {
590   ScopeLogger();
591
592   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
593   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
594
595   picojson::object data = args.get<picojson::object>();
596   picojson::array conversations =
597       data.at(REMOVE_CONVERSATIONS_ARGS_CONVERSATIONS).get<picojson::array>();
598   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
599
600   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
601   picojson::object& obj = json->get<picojson::object>();
602   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
603
604   ConversationCallbackData* callback = new ConversationCallbackData(queue_, callbackId);
605
606   PlatformResult ret(ErrorCode::NO_ERROR);
607   for (auto it = conversations.begin(); it != conversations.end(); ++it) {
608     std::shared_ptr<MessageConversation> conversation;
609     ret = MessagingUtil::jsonToMessageConversation(*it, &conversation);
610     if (ret.IsError()) {
611       delete callback;
612       POST_AND_RETURN(ret, json, obj)
613     }
614     callback->addConversation(conversation);
615   }
616
617   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
618
619   callback->AddToQueue();
620   service->getMsgStorage()->removeConversations(callback);
621 }
622
623 void MessagingInstance::MessageStorageFindFolders(const picojson::value& args,
624                                                   picojson::object& out) {
625   ScopeLogger();
626
627   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
628   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
629
630   picojson::object data = args.get<picojson::object>();
631   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
632
633   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
634   picojson::object& obj = json->get<picojson::object>();
635   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
636
637   AbstractFilterPtr filter;
638   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
639   if (ret.IsError()) {
640     POST_AND_RETURN(ret, json, obj)
641   }
642
643   FoldersCallbackData* callback = new FoldersCallbackData(queue_, callbackId);
644   callback->setFilter(filter);
645
646   callback->AddToQueue();
647   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
648   service->getMsgStorage()->findFolders(callback);
649 }
650
651 void MessagingInstance::MessageStorageAddMessagesChangeListener(const picojson::value& args,
652                                                                 picojson::object& out) {
653   ScopeLogger();
654
655   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
656
657   picojson::object data = args.get<picojson::object>();
658
659   AbstractFilterPtr filter;
660   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
661   if (ret.IsError()) {
662     ReportError(ret, &out);
663     return;
664   }
665
666   int serviceId = getServiceIdFromJSON(data);
667
668   auto service = manager_.getMessageService(serviceId);
669
670   std::shared_ptr<MessagesChangeCallback> callback(
671       new MessagesChangeCallback(kDumbCallbackId, serviceId, service->getMsgServiceType(), queue_));
672
673   callback->setFilter(filter);
674
675   long op_id = service->getMsgStorage()->addMessagesChangeListener(callback);
676
677   picojson::value v(static_cast<double>(op_id));
678   ReportSuccess(v, out);
679 }
680
681 void MessagingInstance::MessageStorageAddConversationsChangeListener(const picojson::value& args,
682                                                                      picojson::object& out) {
683   ScopeLogger();
684
685   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
686
687   picojson::object data = args.get<picojson::object>();
688
689   AbstractFilterPtr filter;
690   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
691   if (ret.IsError()) {
692     ReportError(ret, &out);
693     return;
694   }
695
696   int serviceId = getServiceIdFromJSON(data);
697
698   auto service = manager_.getMessageService(serviceId);
699
700   std::shared_ptr<ConversationsChangeCallback> callback(new ConversationsChangeCallback(
701       static_cast<long>(-1), serviceId, service->getMsgServiceType(), queue_));
702
703   callback->setFilter(filter);
704
705   long op_id = service->getMsgStorage()->addConversationsChangeListener(callback);
706
707   picojson::value v(static_cast<double>(op_id));
708   ReportSuccess(v, out);
709 }
710
711 void MessagingInstance::MessageStorageAddFolderChangeListener(const picojson::value& args,
712                                                               picojson::object& out) {
713   ScopeLogger();
714
715   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
716
717   picojson::object data = args.get<picojson::object>();
718
719   AbstractFilterPtr filter;
720   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
721   if (ret.IsError()) {
722     ReportError(ret, &out);
723     return;
724   }
725
726   int serviceId = getServiceIdFromJSON(data);
727
728   auto service = manager_.getMessageService(serviceId);
729
730   std::shared_ptr<FoldersChangeCallback> callback(new FoldersChangeCallback(
731       static_cast<long>(-1), serviceId, service->getMsgServiceType(), queue_));
732
733   callback->setFilter(filter);
734
735   long op_id = service->getMsgStorage()->addFoldersChangeListener(callback);
736
737   picojson::value v(static_cast<double>(op_id));
738   ReportSuccess(v, out);
739 }
740
741 void MessagingInstance::MessageStorageRemoveChangeListener(const picojson::value& args,
742                                                            picojson::object& out) {
743   ScopeLogger();
744
745   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
746
747   picojson::object data = args.get<picojson::object>();
748   const long watchId =
749       static_cast<long>(data.at(REMOVE_CHANGE_LISTENER_ARGS_WATCHID).get<double>());
750
751   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
752
753   service->getMsgStorage()->removeChangeListener(watchId);
754   ReportSuccess(out);
755 }
756
757 void MessagingInstance::MessageGetMessageStatus(const picojson::value& args,
758                                                 picojson::object& out) {
759   ScopeLogger();
760
761   picojson::object data = args.get<picojson::object>();
762   const int id = stoi(data.at("id").get<std::string>());
763   const std::string& type = data.at("type").get<std::string>();
764
765   std::string status;
766   if (FUN_MESSAGE_MESSAGING_EMAIL == type) {
767     status = EmailManager::getInstance().getMessageStatus(id);
768   } else {
769     status = ShortMsgManager::getInstance().getMessageStatus(id);
770   }
771
772   ReportSuccess(picojson::value(status), out);
773 }
774
775 }  // namespace messaging
776 }  // namespace extension