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