Merge branch 'tizen_4.0' into tizen
[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 EmailManager& MessagingInstance::getEmailManager() {
178   return email_manager_;
179 }
180
181 ShortMsgManager& MessagingInstance::getShortMsgManager() {
182   return short_msg_manager_;
183 }
184
185 void MessagingInstance::GetMessageServices(const picojson::value& args, picojson::object& out) {
186   ScopeLogger();
187
188   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
189
190   picojson::value serviceTag =
191       args.get<picojson::object>().at(GET_MESSAGE_SERVICES_ARGS_MESSAGE_SERVICE_TYPE);
192   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
193   // above values should be validated in js
194   manager_.getMessageServices(serviceTag.to_str(), callbackId);
195 }
196
197 void MessagingInstance::MessageServiceSendMessage(const picojson::value& args,
198                                                   picojson::object& out) {
199   ScopeLogger();
200
201   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
202   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
203
204   picojson::object data = args.get<picojson::object>();
205   picojson::value v_message = data.at(SEND_MESSAGE_ARGS_MESSAGE);
206   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
207
208   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
209   picojson::object& obj = json->get<picojson::object>();
210   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
211
212   std::shared_ptr<Message> message;
213   PlatformResult ret = MessagingUtil::jsonToMessage(v_message, &message, *this);
214   if (ret.IsError()) {
215     POST_AND_RETURN(ret, json, obj)
216   }
217
218   MessageRecipientsCallbackData* callback =
219       new MessageRecipientsCallbackData(queue_, callbackId, *this);
220   long simIndex = 0;
221   int serviceId = 0;
222
223   callback->setMessage(message);
224   serviceId = getServiceIdFromJSON(data);
225   callback->setAccountId(serviceId);
226   simIndex = static_cast<long>(
227       MessagingUtil::getValueFromJSONObject<double>(data, SEND_MESSAGE_ARGS_SIMINDEX));
228
229   bool cell_support = false;
230   system_info_get_platform_bool("http://tizen.org/feature/network.telephony", &cell_support);
231   if (cell_support) {
232     LoggerD("cell_support is true");
233     if (!callback->setSimIndex(simIndex)) {
234       delete callback;
235       callback = nullptr;
236       POST_AND_RETURN(PlatformResult(ErrorCode::UNKNOWN_ERR, "set sim index failed"), json, obj)
237     }
238   } else {
239     LoggerD("cell_support is false");
240   }
241
242   callback->AddToQueue();
243   auto service = manager_.getMessageService(serviceId);
244
245   ret = service->sendMessage(callback);
246   if (!ret) {
247     POST_AND_RETURN(ret, json, obj)
248   }
249 }
250
251 void MessagingInstance::MessageServiceLoadMessageBody(const picojson::value& args,
252                                                       picojson::object& out) {
253   ScopeLogger();
254
255   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
256   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
257
258   picojson::object data = args.get<picojson::object>();
259
260   picojson::value json_message = data.at(ADD_DRAFT_MESSAGE_ARGS_MESSAGE);
261   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
262
263   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
264   picojson::object& obj = json->get<picojson::object>();
265   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
266
267   std::shared_ptr<Message> message;
268   PlatformResult ret = MessagingUtil::jsonToMessage(json_message, &message, *this);
269   if (ret.IsError()) {
270     POST_AND_RETURN(ret, json, obj)
271   }
272
273   MessageBodyCallbackData* callback = new MessageBodyCallbackData(queue_, callbackId, *this);
274
275   callback->setMessage(message);
276
277   callback->AddToQueue();
278   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
279   ret = service->loadMessageBody(callback);
280   if (ret.IsError()) {
281     POST_AND_RETURN(ret, json, obj)
282   }
283 }
284
285 void MessagingInstance::MessageServiceLoadMessageAttachment(const picojson::value& args,
286                                                             picojson::object& out) {
287   ScopeLogger();
288
289   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
290   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
291
292   picojson::object data = args.get<picojson::object>();
293   picojson::value attachment = data.at(LOAD_MESSAGE_ATTACHMENT_ARGS_ATTACHMENT);
294   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
295
296   MessageAttachmentCallbackData* callback =
297       new MessageAttachmentCallbackData(queue_, callbackId, *this);
298   callback->setMessageAttachment(MessagingUtil::jsonToMessageAttachment(attachment));
299
300   callback->AddToQueue();
301   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
302   const auto result = service->loadMessageAttachment(callback);
303   if (result.IsError()) {
304     auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
305     picojson::object& obj = json->get<picojson::object>();
306     obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
307     POST_AND_RETURN(result, json, obj)
308   }
309 }
310
311 void MessagingInstance::MessageServiceSync(const picojson::value& args, picojson::object& out) {
312   ScopeLogger();
313
314   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
315   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
316
317   picojson::object data = args.get<picojson::object>();
318   picojson::value v_id = data.at(SYNC_ARGS_ID);
319   picojson::value v_limit = data.at(SYNC_ARGS_LIMIT);
320   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
321
322   int id = -1;
323   try {
324     id = std::stoi(v_id.get<std::string>());
325   } catch (...) {
326     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out,
327                       ("Problem with MessageService"));
328     return;
329   }
330   long limit = 0;
331   if (v_limit.is<double>()) {
332     limit = static_cast<long>(v_limit.get<double>());
333   }
334
335   SyncCallbackData* callback = new SyncCallbackData(queue_, callbackId, *this);
336   callback->setAccountId(id);
337   callback->setLimit(limit);
338
339   callback->AddToQueue();
340   long op_id = -1;
341
342   const auto result = manager_.getMessageService(id)->sync(callback, &op_id);
343
344   if (result) {
345     ReportSuccess(picojson::value(static_cast<double>(op_id)), out);
346   } else {
347     LogAndReportError(result, &out);
348   }
349 }
350
351 void MessagingInstance::MessageServiceSyncFolder(const picojson::value& args,
352                                                  picojson::object& out) {
353   ScopeLogger();
354
355   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
356   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
357
358   picojson::object data = args.get<picojson::object>();
359   picojson::value v_id = data.at(SYNC_FOLDER_ARGS_ID);
360   picojson::value v_folder = data.at(SYNC_FOLDER_ARGS_FOLDER);
361   picojson::value v_limit = data.at(SYNC_FOLDER_ARGS_LIMIT);
362   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
363
364   int id = -1;
365   try {
366     id = std::stoi(v_id.get<std::string>());
367   } catch (...) {
368     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out,
369                       ("Problem with MessageService"));
370     return;
371   }
372
373   long limit = 0;
374   if (v_limit.is<double>()) {
375     limit = static_cast<long>(v_limit.get<double>());
376   }
377
378   SyncFolderCallbackData* callback = new SyncFolderCallbackData(queue_, callbackId, *this);
379   callback->setAccountId(id);
380   callback->setMessageFolder(MessagingUtil::jsonToMessageFolder(v_folder));
381   callback->setLimit(limit);
382
383   callback->AddToQueue();
384   long op_id = -1;
385
386   const auto result = manager_.getMessageService(id)->syncFolder(callback, &op_id);
387   if (result) {
388     ReportSuccess(picojson::value(static_cast<double>(op_id)), out);
389   } else {
390     LogAndReportError(result, &out);
391   }
392 }
393
394 void MessagingInstance::MessageServiceStopSync(const picojson::value& args, picojson::object& out) {
395   ScopeLogger();
396   CHECK_EXIST(args, STOP_SYNC_ARGS_OPID, out);
397
398   picojson::object data = args.get<picojson::object>();
399
400   if (data.find(STOP_SYNC_ARGS_ID) != data.end()) {
401     picojson::value v_id = data.at(STOP_SYNC_ARGS_ID);
402     picojson::value v_op_id = data.at(STOP_SYNC_ARGS_OPID);
403
404     int id = -1;
405     try {
406       id = std::stoi(v_id.get<std::string>());
407     } catch (...) {
408       LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out,
409                         ("Problem with MessageService"));
410       return;
411     }
412
413     long op_id = 0;
414     if (v_op_id.is<double>()) {
415       op_id = static_cast<long>(v_op_id.get<double>());
416     }
417
418     const auto result = manager_.getMessageService(id)->stopSync(op_id);
419
420     if (result) {
421       ReportSuccess(out);
422     } else {
423       LogAndReportError(result, &out);
424     }
425   } else {
426     LogAndReportError(PlatformResult(ErrorCode::UNKNOWN_ERR), &out, ("Unknown error"));
427   }
428 }
429
430 void MessagingInstance::MessageStorageAddDraft(const picojson::value& args, picojson::object& out) {
431   ScopeLogger();
432
433   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
434   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
435
436   picojson::object data = args.get<picojson::object>();
437   picojson::value v_message = data.at(ADD_DRAFT_MESSAGE_ARGS_MESSAGE);
438   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
439
440   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
441   picojson::object& obj = json->get<picojson::object>();
442   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
443
444   std::shared_ptr<Message> message;
445   PlatformResult ret = MessagingUtil::jsonToMessage(v_message, &message, *this);
446   if (ret.IsError()) {
447     POST_AND_RETURN(ret, json, obj)
448   }
449
450   MessageCallbackUserData* callback = new MessageCallbackUserData(queue_, callbackId, *this);
451   callback->setMessage(message);
452
453   int serviceId = getServiceIdFromJSON(data);
454   callback->setAccountId(serviceId);
455
456   callback->AddToQueue();
457   auto service = manager_.getMessageService(serviceId);
458   service->getMsgStorage()->addDraftMessage(callback);
459 }
460
461 void MessagingInstance::MessageStorageFindMessages(const picojson::value& args,
462                                                    picojson::object& out) {
463   ScopeLogger();
464
465   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
466   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
467
468   picojson::object data = args.get<picojson::object>();
469   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
470
471   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
472   picojson::object& obj = json->get<picojson::object>();
473   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
474
475   AbstractFilterPtr filter;
476   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
477   if (ret.IsError()) {
478     POST_AND_RETURN(ret, json, obj)
479   }
480   auto sortMode = MessagingUtil::jsonToSortMode(data);
481
482   long limit = static_cast<long>(
483       MessagingUtil::getValueFromJSONObject<double>(data, FIND_FOLDERS_ARGS_LIMIT));
484
485   long offset = static_cast<long>(
486       MessagingUtil::getValueFromJSONObject<double>(data, FIND_FOLDERS_ARGS_OFFSET));
487
488   int serviceId = getServiceIdFromJSON(data);
489   auto storage = manager_.getMessageService(serviceId)->getMsgStorage();
490
491   FindMsgCallbackUserData* callback = new FindMsgCallbackUserData(queue_, callbackId, *this);
492   callback->setFilter(filter);
493   callback->setLimit(limit);
494   callback->setOffset(offset);
495   callback->setAccountId(serviceId);
496   callback->setSortMode(sortMode);
497
498   callback->AddToQueue();
499   storage->findMessages(callback);
500 }
501
502 void MessagingInstance::MessageStorageRemoveMessages(const picojson::value& args,
503                                                      picojson::object& out) {
504   ScopeLogger();
505
506   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
507   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
508
509   picojson::object data = args.get<picojson::object>();
510   picojson::array messages = data.at(REMOVE_MESSAGES_ARGS_MESSAGES).get<picojson::array>();
511   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
512
513   MessagesCallbackUserData* callback = new MessagesCallbackUserData(queue_, callbackId, *this);
514
515   auto each = [callback, this](picojson::value& v) -> void {
516     std::shared_ptr<Message> message;
517     PlatformResult ret = MessagingUtil::jsonToMessage(v, &message, *this);
518     if (ret.IsSuccess()) {
519       callback->addMessage(message);
520     }
521   };
522
523   for_each(messages.begin(), messages.end(), each);
524
525   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
526
527   callback->AddToQueue();
528   service->getMsgStorage()->removeMessages(callback);
529 }
530
531 void MessagingInstance::MessageStorageUpdateMessages(const picojson::value& args,
532                                                      picojson::object& out) {
533   ScopeLogger();
534
535   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
536   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
537
538   picojson::object data = args.get<picojson::object>();
539   picojson::value pico_messages = data.at(UPDATE_MESSAGES_ARGS_MESSAGES);
540   auto pico_array = pico_messages.get<picojson::array>();
541   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
542
543   auto callback = new MessagesCallbackUserData(queue_, callbackId, *this);
544
545   std::for_each(pico_array.begin(), pico_array.end(),
546                 [&callback, this](picojson::value& v) -> void {
547                   std::shared_ptr<Message> message;
548                   PlatformResult ret = MessagingUtil::jsonToMessage(v, &message, *this);
549                   if (ret.IsSuccess()) {
550                     callback->addMessage(message);
551                   }
552                 });
553
554   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
555
556   callback->AddToQueue();
557   service->getMsgStorage()->updateMessages(callback);
558 }
559
560 void MessagingInstance::MessageStorageFindConversations(const picojson::value& args,
561                                                         picojson::object& out) {
562   ScopeLogger();
563
564   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
565   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
566
567   picojson::object data = args.get<picojson::object>();
568   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
569
570   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
571   picojson::object& obj = json->get<picojson::object>();
572   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
573
574   AbstractFilterPtr filter;
575   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
576   if (ret.IsError()) {
577     POST_AND_RETURN(ret, json, obj)
578   }
579   auto sortMode = MessagingUtil::jsonToSortMode(data);
580   long limit = static_cast<long>(
581       MessagingUtil::getValueFromJSONObject<double>(data, FIND_CONVERSATIONS_ARGS_LIMIT));
582   long offset = static_cast<long>(
583       MessagingUtil::getValueFromJSONObject<double>(data, FIND_CONVERSATIONS_ARGS_OFFSET));
584
585   int serviceId = getServiceIdFromJSON(data);
586
587   ConversationCallbackData* callback = new ConversationCallbackData(queue_, callbackId, *this);
588   callback->setFilter(filter);
589   callback->setLimit(limit);
590   callback->setOffset(offset);
591   callback->setAccountId(serviceId);
592   callback->setSortMode(sortMode);
593
594   callback->AddToQueue();
595   auto storage = manager_.getMessageService(serviceId)->getMsgStorage();
596   storage->findConversations(callback);
597 }
598
599 void MessagingInstance::MessageStorageRemoveConversations(const picojson::value& args,
600                                                           picojson::object& out) {
601   ScopeLogger();
602
603   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingWrite, &out);
604   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
605
606   picojson::object data = args.get<picojson::object>();
607   picojson::array conversations =
608       data.at(REMOVE_CONVERSATIONS_ARGS_CONVERSATIONS).get<picojson::array>();
609   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
610
611   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
612   picojson::object& obj = json->get<picojson::object>();
613   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
614
615   ConversationCallbackData* callback = new ConversationCallbackData(queue_, callbackId, *this);
616
617   PlatformResult ret(ErrorCode::NO_ERROR);
618   for (auto it = conversations.begin(); it != conversations.end(); ++it) {
619     std::shared_ptr<MessageConversation> conversation;
620     ret = MessagingUtil::jsonToMessageConversation(*it, &conversation);
621     if (ret.IsError()) {
622       delete callback;
623       POST_AND_RETURN(ret, json, obj)
624     }
625     callback->addConversation(conversation);
626   }
627
628   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
629
630   callback->AddToQueue();
631   service->getMsgStorage()->removeConversations(callback);
632 }
633
634 void MessagingInstance::MessageStorageFindFolders(const picojson::value& args,
635                                                   picojson::object& out) {
636   ScopeLogger();
637
638   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
639   CHECK_EXIST(args, JSON_CALLBACK_ID, out);
640
641   picojson::object data = args.get<picojson::object>();
642   const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
643
644   auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
645   picojson::object& obj = json->get<picojson::object>();
646   obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
647
648   AbstractFilterPtr filter;
649   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
650   if (ret.IsError()) {
651     POST_AND_RETURN(ret, json, obj)
652   }
653
654   FoldersCallbackData* callback = new FoldersCallbackData(queue_, callbackId, *this);
655   callback->setFilter(filter);
656
657   callback->AddToQueue();
658   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
659   service->getMsgStorage()->findFolders(callback);
660 }
661
662 void MessagingInstance::MessageStorageAddMessagesChangeListener(const picojson::value& args,
663                                                                 picojson::object& out) {
664   ScopeLogger();
665
666   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
667
668   picojson::object data = args.get<picojson::object>();
669
670   AbstractFilterPtr filter;
671   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
672   if (ret.IsError()) {
673     ReportError(ret, &out);
674     return;
675   }
676
677   int serviceId = getServiceIdFromJSON(data);
678
679   auto service = manager_.getMessageService(serviceId);
680
681   std::shared_ptr<MessagesChangeCallback> callback(new MessagesChangeCallback(
682       kDumbCallbackId, serviceId, service->getMsgServiceType(), queue_, *this));
683
684   callback->setFilter(filter);
685
686   long op_id = service->getMsgStorage()->addMessagesChangeListener(callback);
687
688   picojson::value v(static_cast<double>(op_id));
689   ReportSuccess(v, out);
690 }
691
692 void MessagingInstance::MessageStorageAddConversationsChangeListener(const picojson::value& args,
693                                                                      picojson::object& out) {
694   ScopeLogger();
695
696   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
697
698   picojson::object data = args.get<picojson::object>();
699
700   AbstractFilterPtr filter;
701   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
702   if (ret.IsError()) {
703     ReportError(ret, &out);
704     return;
705   }
706
707   int serviceId = getServiceIdFromJSON(data);
708
709   auto service = manager_.getMessageService(serviceId);
710
711   std::shared_ptr<ConversationsChangeCallback> callback(new ConversationsChangeCallback(
712       static_cast<long>(-1), serviceId, service->getMsgServiceType(), queue_, *this));
713
714   callback->setFilter(filter);
715
716   long op_id = service->getMsgStorage()->addConversationsChangeListener(callback);
717
718   picojson::value v(static_cast<double>(op_id));
719   ReportSuccess(v, out);
720 }
721
722 void MessagingInstance::MessageStorageAddFolderChangeListener(const picojson::value& args,
723                                                               picojson::object& out) {
724   ScopeLogger();
725
726   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
727
728   picojson::object data = args.get<picojson::object>();
729
730   AbstractFilterPtr filter;
731   PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
732   if (ret.IsError()) {
733     ReportError(ret, &out);
734     return;
735   }
736
737   int serviceId = getServiceIdFromJSON(data);
738
739   auto service = manager_.getMessageService(serviceId);
740
741   std::shared_ptr<FoldersChangeCallback> callback(new FoldersChangeCallback(
742       static_cast<long>(-1), serviceId, service->getMsgServiceType(), queue_, *this));
743
744   callback->setFilter(filter);
745
746   long op_id = service->getMsgStorage()->addFoldersChangeListener(callback);
747
748   picojson::value v(static_cast<double>(op_id));
749   ReportSuccess(v, out);
750 }
751
752 void MessagingInstance::MessageStorageRemoveChangeListener(const picojson::value& args,
753                                                            picojson::object& out) {
754   ScopeLogger();
755
756   CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
757
758   picojson::object data = args.get<picojson::object>();
759   const long watchId =
760       static_cast<long>(data.at(REMOVE_CHANGE_LISTENER_ARGS_WATCHID).get<double>());
761
762   auto service = manager_.getMessageService(getServiceIdFromJSON(data));
763
764   service->getMsgStorage()->removeChangeListener(watchId);
765   ReportSuccess(out);
766 }
767
768 void MessagingInstance::MessageGetMessageStatus(const picojson::value& args,
769                                                 picojson::object& out) {
770   ScopeLogger();
771
772   picojson::object data = args.get<picojson::object>();
773   const int id = stoi(data.at("id").get<std::string>());
774   const std::string& type = data.at("type").get<std::string>();
775
776   std::string status;
777   if (FUN_MESSAGE_MESSAGING_EMAIL == type) {
778     status = email_manager_.getMessageStatus(id);
779   } else {
780     status = short_msg_manager_.getMessageStatus(id);
781   }
782
783   ReportSuccess(picojson::value(status), out);
784 }
785
786 }  // namespace messaging
787 }  // namespace extension