return op_id++;
}
-/**
- * Attribute | Attribute filter| Attribute range filter
- * | supported | supported
- * ----------------+-----------------+------------------------
- * id | Yes | No
- * parentId | Yes | No
- * serviceId | Yes | No
- * contentType | Yes | No
- * name | Yes | No
- * path | Yes | No
- * type | Yes | No
- * synchronizable | Yes | No
- **/
-
-PlatformResult EmailManager::FindFoldersPlatform(FoldersCallbackData* callback) {
- ScopeLogger();
- int ret = EMAIL_ERROR_UNKNOWN;
- email_mailbox_t* mailboxes = NULL;
- int mailboxes_count = 0;
-
- SCOPE_EXIT {
- if (mailboxes != NULL) {
- if (EMAIL_ERROR_NONE != email_free_mailbox(&mailboxes, mailboxes_count)) {
- LoggerW("Free mailboxes failed: %d", ret);
- }
- }
- };
-
-
- tizen::AbstractFilterPtr filter = callback->getFilter();
- if (!filter) {
- return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Filter not provided");
- }
-
- std::lock_guard<std::mutex> lock(m_mutex);
- auto account_id = callback->getMessageStorageId();
-
- if (account_id < 0) {
- LoggerD("account_id < 0");
- return PlatformResult(ErrorCode::UNKNOWN_ERR, "An unknown error occurred");
- }
-
- LoggerD("Listing folders for account ID: %d", account_id);
- ret = email_get_mailbox_list(account_id, -1, &mailboxes, &mailboxes_count);
- if (EMAIL_ERROR_NONE != ret || !mailboxes) {
- return LogAndCreateResult(
- ErrorCode::UNKNOWN_ERR, "Platform error, cannot get folders",
- ("email_get_mailbox_list error: %d (%s)", ret, get_error_message(ret)));
- }
-
- LoggerD("Found mailboxes: %d", mailboxes_count);
- for (int i = 0; i < mailboxes_count; ++i) {
- auto fd = std::make_shared<MessageFolder>(mailboxes[i]);
- if (filter->isMatching(fd.get())) {
- callback->addFolder(fd);
- }
- }
-
- return PlatformResult(ErrorCode::NO_ERROR);
-}
-
-void EmailManager::findFolders(FoldersCallbackData* callback) {
- ScopeLogger();
-
- if (!callback) {
- LoggerE("Callback is null");
- return;
- }
-
- PlatformResult ret = FindFoldersPlatform(callback);
- if (ret.IsError()) {
- LoggerE("%d (%s)", static_cast<int>(ret.error_code()), (ret.message()).c_str());
- callback->SetError(ret);
- }
-
- // Complete task
- LoggerD("callback: %p error:%d folders.size()=%zu", callback, callback->IsError(),
- callback->getFolders().size());
-
- if (callback->IsError()) {
- LoggerD("Calling error callback");
- } else {
- LoggerD("Calling success callback");
-
- std::vector<picojson::value> response;
- auto folders = callback->getFolders();
- std::for_each(folders.begin(), folders.end(),
- [&response](std::shared_ptr<MessageFolder>& folder) {
- response.push_back(MessagingUtil::folderToJson(folder));
- });
-
- callback->SetSuccess(picojson::value(response));
- }
-
- callback->Post();
-
- delete callback;
- callback = NULL;
-}
-
PlatformResult EmailManager::RemoveConversationsPlatform(ConversationCallbackData* callback) {
ScopeLogger();
int error;
void updateMessages(MessagesCallbackUserData* callback);
void findMessages(FindMsgCallbackUserData* callback);
void findConversations(ConversationCallbackData* callback);
- void findFolders(FoldersCallbackData* callback);
void removeConversations(ConversationCallbackData* callback);
std::string getMessageStatus(int id);
common::PlatformResult RemoveMessagesPlatform(MessagesCallbackUserData* callback);
common::PlatformResult FindMessagesPlatform(FindMsgCallbackUserData* callback);
common::PlatformResult FindConversationsPlatform(ConversationCallbackData* callback);
- common::PlatformResult FindFoldersPlatform(FoldersCallbackData* callback);
common::PlatformResult RemoveConversationsPlatform(ConversationCallbackData* callback);
typedef std::map<int, MessageRecipientsCallbackData*> SendReqMap;
return true;
}
-} // namespace
-
+} // namespace
namespace extension {
namespace messaging {
#include "conversation_callback_data.h"
#include "find_msg_callback_user_data.h"
-#include "folders_callback_data.h"
#include "message_callback_user_data.h"
#include "messages_callback_user_data.h"
#include "messaging_util.h"
virtual void findMessages(FindMsgCallbackUserData* callback) = 0;
virtual void findConversations(ConversationCallbackData* callback) = 0;
virtual void removeConversations(ConversationCallbackData* callback) = 0;
- virtual void findFolders(FoldersCallbackData* callback) = 0;
+ virtual void findFolders(FindFoldersTaskParams* params) = 0;
// Listeners registration/removal is common for all types of storage
// and does not have to be overwritten in derived classes.
#include <glib.h>
#include "common/platform_exception.h"
+#include "common/platform_result.h"
+#include "common/scope_exit.h"
+#include "common/tools.h"
#include "email_manager.h"
#include "message.h"
#include "messaging_instance.h"
+#include "messaging_util.h"
+
+#include "messaging_native.h"
+
+using common::ErrorCode;
+using common::tools::ReportError;
+using common::tools::ReportSuccess;
+using common::Instance;
+using common::PlatformResult;
namespace extension {
namespace messaging {
}
}
-static gboolean findFoldersTask(void* data) {
+static gboolean FindFoldersGlibTask(void* data) {
ScopeLogger();
+ picojson::object response;
+ std::unique_ptr<FindFoldersTaskParams> params(static_cast<FindFoldersTaskParams*>(data));
- FoldersCallbackData* callback = static_cast<FoldersCallbackData*>(data);
- callback->getEmailManager().findFolders(callback);
+ if (!params) {
+ LoggerE("FindFoldersGlibTask received null arguments.");
+ return FALSE;
+ }
+
+ std::vector<MessageFolder> folders;
+ PlatformResult ret = native::EmailGetMailboxList(params->account_id, folders);
+ if (ret.IsError()) {
+ ReportError(ret, &response);
+ Instance::PostMessage(params->instance, picojson::value(response));
+ return FALSE;
+ }
+ auto json = picojson::value(picojson::array());
+ auto& folders_list = json.get<picojson::array>();
+ for (const auto& folder : folders) {
+ if (params->filter->isMatching(&folder)) {
+ folders_list.push_back(MessagingUtil::folderToJson(folder));
+ }
+ }
+
+ response[JSON_CALLBACK_ID] = picojson::value(static_cast<double>(params->callback_id));
+ ReportSuccess(json, response);
+ Instance::PostMessage(params->instance, picojson::value(response));
return FALSE;
}
-void MessageStorageEmail::findFolders(FoldersCallbackData* callback) {
+void MessageStorageEmail::findFolders(FindFoldersTaskParams* params) {
ScopeLogger();
-
- if (!callback) {
- LoggerE("Callback is null");
- return;
- }
-
- guint id = g_idle_add(findFoldersTask, static_cast<void*>(callback));
- if (!id) {
- LoggerE("g_idle_add failed");
- delete callback;
- callback = NULL;
+ guint ret = g_idle_add(FindFoldersGlibTask, params);
+ if (!ret) {
+ LoggerE("Failed to set FindFoldersGlibTask.");
+ delete params;
}
}
virtual void findMessages(FindMsgCallbackUserData* callback);
virtual void findConversations(ConversationCallbackData* callback);
virtual void removeConversations(ConversationCallbackData* callback);
- virtual void findFolders(FoldersCallbackData* callback);
+ virtual void findFolders(FindFoldersTaskParams* callback);
};
} // messaging
#include "common/logger.h"
#include "common/platform_exception.h"
+#include "common/platform_result.h"
+#include "common/scope_exit.h"
+#include "common/tools.h"
#include "message_sms.h"
#include "message_storage_short_msg.h"
#include "messaging_util.h"
#include "short_message_manager.h"
+using common::ErrorCode;
+using common::tools::ReportError;
+using common::tools::ReportSuccess;
+using common::Instance;
+using common::PlatformResult;
+
namespace extension {
namespace messaging {
static gboolean findFoldersCB(void* data) {
ScopeLogger();
+ std::unique_ptr<FindFoldersTaskParams> params(static_cast<FindFoldersTaskParams*>(data));
- FoldersCallbackData* callback = static_cast<FoldersCallbackData*>(data);
+ std::string content_type = params->message_type;
+ FolderPtr folder;
+ picojson::object response;
picojson::array array;
- auto each = [&array](std::shared_ptr<MessageFolder> folder) -> void {
- array.push_back(MessagingUtil::folderToJson(folder));
- };
-
- auto folders = callback->getFolders();
- for_each(folders.begin(), folders.end(), each);
-
- callback->SetSuccess(picojson::value(array));
- callback->Post();
+ for (int i = MESSAGE_FOLDER_TYPE_INBOX; i < MESSAGE_FOLDER_TYPE_NOTSTANDARD; ++i) {
+ MessageFolder folder(
+ std::to_string(i), "", std::to_string(params->account_id), content_type,
+ MessagingUtil::messageFolderTypeToString(static_cast<MessageFolderType>(i)), "",
+ static_cast<MessageFolderType>(i), false);
- delete callback;
- callback = NULL;
+ if (params->filter->isMatching(&folder)) {
+ array.push_back(MessagingUtil::folderToJson(folder));
+ }
+ }
+ response[JSON_CALLBACK_ID] = picojson::value(static_cast<double>(params->callback_id));
+ ReportSuccess(picojson::value(array), response);
+ Instance::PostMessage(params->instance, picojson::value(response));
return FALSE;
}
-void MessageStorageShortMsg::findFolders(FoldersCallbackData* callback) {
+void MessageStorageShortMsg::findFolders(FindFoldersTaskParams* params) {
ScopeLogger();
- if (!callback) {
- LoggerE("Callback is null");
+ if (!params) {
+ LoggerE("FindFoldersTaskParams is null");
return;
}
-
- std::string content_type = getMsgServiceTypeString();
- FolderPtr folder;
-
- auto filter = callback->getFilter();
- for (int i = MESSAGE_FOLDER_TYPE_INBOX; i < MESSAGE_FOLDER_TYPE_NOTSTANDARD; ++i) {
- folder = std::make_shared<MessageFolder>(
- std::to_string(i), "", std::to_string(m_id), content_type,
- MessagingUtil::messageFolderTypeToString(static_cast<MessageFolderType>(i)), "", static_cast<MessageFolderType>(i),
- false);
- if (filter->isMatching(folder.get())) {
- callback->addFolder(folder);
- }
- }
-
- guint id = g_idle_add(findFoldersCB, static_cast<void*>(callback));
+ guint id = g_idle_add(findFoldersCB, static_cast<void*>(params));
if (!id) {
LoggerE("g_idle_add failed");
- delete callback;
- callback = NULL;
}
}
virtual void findMessages(FindMsgCallbackUserData* callback);
virtual void findConversations(ConversationCallbackData* callback);
virtual void removeConversations(ConversationCallbackData* callback);
- virtual void findFolders(FoldersCallbackData* callback);
+ virtual void findFolders(FindFoldersTaskParams* params);
};
} // messaging
],
},
'sources': [
+ 'messaging_native.cc',
+ 'messaging_native.h',
'messaging_api.js',
'callback_user_data.cc',
'callback_user_data.h',
#include "conversations_change_callback.h"
#include "email_manager.h"
#include "find_msg_callback_user_data.h"
-#include "folders_callback_data.h"
#include "folders_change_callback.h"
#include "message.h"
#include "message_storage.h"
using common::ErrorCode;
using common::TypeMismatchException;
using common::PlatformResult;
+using common::tools::ReportError;
namespace extension {
namespace messaging {
const char* FUNCTIONS_HIDDEN_ARGS_SERVICE_ID = "serviceId";
const char* FUN_MESSAGE_MESSAGING_EMAIL = "messaging.email";
-auto getServiceIdFromJSON = [](picojson::object& data) -> int {
- std::string serviceStrId;
+int getServiceIdFromJSON(const picojson::object& data) {
try {
- serviceStrId =
- MessagingUtil::getValueFromJSONObject<std::string>(data, FUNCTIONS_HIDDEN_ARGS_SERVICE_ID);
- return std::stoi(serviceStrId);
+ return std::stoi(
+ MessagingUtil::getValueFromJSONObject<std::string>(data, FUNCTIONS_HIDDEN_ARGS_SERVICE_ID));
} catch (...) {
return -1;
}
CHECK_PRIVILEGE_ACCESS(kPrivilegeMessagingRead, &out);
CHECK_EXIST(args, JSON_CALLBACK_ID, out);
- picojson::object data = args.get<picojson::object>();
- const double callbackId = args.get(JSON_CALLBACK_ID).get<double>();
+ const auto& data = args.get<picojson::object>();
+ auto service = manager_.getMessageService(getServiceIdFromJSON(data));
- auto json = std::shared_ptr<picojson::value>(new picojson::value(picojson::object()));
- picojson::object& obj = json->get<picojson::object>();
- obj[JSON_CALLBACK_ID] = picojson::value(callbackId);
+ auto task_params = new FindFoldersTaskParams();
+ task_params->instance = this;
+ task_params->callback_id = args.get(JSON_CALLBACK_ID).get<double>();
+ task_params->account_id = service->getMsgServiceId();
+ task_params->message_type = service->getMsgServiceTypeString();
- AbstractFilterPtr filter;
- PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &filter);
+ PlatformResult ret = MessagingUtil::jsonToAbstractFilter(data, &(task_params->filter));
if (ret.IsError()) {
- POST_AND_RETURN(ret, json, obj)
+ LoggerE("Cannot convert json to AbstractFilter: %s", args.serialize().c_str());
+ ReportError(ret, &out);
+ delete task_params;
+ return;
}
- FoldersCallbackData* callback = new FoldersCallbackData(queue_, callbackId, *this);
- callback->setFilter(filter);
-
- callback->AddToQueue();
- auto service = manager_.getMessageService(getServiceIdFromJSON(data));
- callback->setMessageStorageId(service->getMsgServiceId());
- service->getMsgStorage()->findFolders(callback);
+ service->getMsgStorage()->findFolders(task_params);
}
void MessagingInstance::MessageStorageAddMessagesChangeListener(const picojson::value& args,
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messaging_native.h"
+#include "common/logger.h"
+#include "common/platform_result.h"
+#include "common/scope_exit.h"
+#include "message_folder.h"
+
+#include <email-api-mailbox.h>
+
+#include <vector>
+
+using extension::messaging::MessageFolder;
+using common::PlatformResult;
+using common::ErrorCode;
+
+namespace native {
+
+PlatformResult EmailGetMailboxList(int account_id, email_mailbox_t** mailboxes, int* count) {
+ ScopeLogger("account id: %d", account_id);
+ int ret = email_get_mailbox_list(account_id, -1, mailboxes, count);
+ if (EMAIL_ERROR_NONE != ret) {
+ LoggerE("Calling email_get_mailbox_list() failed.");
+ return PlatformResult(ErrorCode::UNKNOWN_ERR, "Calling email_get_mailbox_list() failed.");
+ }
+ return PlatformResult();
+}
+
+PlatformResult EmailGetMailboxList(int account_id, std::vector<MessageFolder>& folders) {
+ email_mailbox_t* mailboxes = nullptr;
+ int count = 0;
+
+ SCOPE_EXIT {
+ email_free_mailbox(&mailboxes, count);
+ };
+
+ auto ret = EmailGetMailboxList(account_id, &mailboxes, &count);
+ if (ret.IsError()) {
+ return ret;
+ }
+
+ for (int i = 0; i < count; ++i) {
+ folders.push_back(MessageFolder(mailboxes[i]));
+ }
+
+ return PlatformResult();
+}
+
+} // namespace native
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ---------------------------------------------------------------------
+ * The purpose of this module is to wrap native messaging API to make WebAPI
+ * implementation less verbose. Actions such as logging and conversion of integer
+ * native error code value to PlatformResult have been scattered across the entire
+ * API implementation, so placing them in a wrapper function will remove a lot of
+ * repeating, verbose code form WebAPI.
+ *
+ * Also in the future if we decide to unit test our API this wrappers will make it easier
+ * to create native api mock.
+ */
+#ifndef MESSAGING_NATIVE_H_
+#define MESSAGING_NATIVE_H_
+
+#include <vector>
+#include "common/platform_result.h"
+#include "message_folder.h"
+
+using extension::messaging::MessageFolder;
+
+namespace native {
+
+common::PlatformResult EmailGetMailboxList(int account_id, std::vector<MessageFolder>& folders);
+
+} // namespace native
+
+#endif // MESSAGING_NATIVE_H_
return v;
}
-picojson::value MessagingUtil::folderToJson(std::shared_ptr<MessageFolder> folder) {
+picojson::value MessagingUtil::folderToJson(const MessageFolder& folder) {
ScopeLogger();
-
picojson::object o;
-
- o[MESSAGE_FOLDER_ATTRIBUTE_ID] = picojson::value(folder->getId());
+ o[MESSAGE_FOLDER_ATTRIBUTE_ID] = picojson::value(folder.getId());
o[MESSAGE_FOLDER_ATTRIBUTE_PARENT_ID] =
- folder->isParentIdSet() ? picojson::value(folder->getParentId()) : picojson::value();
- o[MESSAGE_FOLDER_ATTRIBUTE_SERVICE_ID] = picojson::value(folder->getServiceId());
- o[MESSAGE_FOLDER_ATTRIBUTE_CONTENT_TYPE] = picojson::value(folder->getContentType());
- o[MESSAGE_FOLDER_ATTRIBUTE_NAME] = picojson::value(folder->getName());
- o[MESSAGE_FOLDER_ATTRIBUTE_PATH] = picojson::value(folder->getPath());
+ folder.isParentIdSet() ? picojson::value(folder.getParentId()) : picojson::value();
+ o[MESSAGE_FOLDER_ATTRIBUTE_SERVICE_ID] = picojson::value(folder.getServiceId());
+ o[MESSAGE_FOLDER_ATTRIBUTE_CONTENT_TYPE] = picojson::value(folder.getContentType());
+ o[MESSAGE_FOLDER_ATTRIBUTE_NAME] = picojson::value(folder.getName());
+ o[MESSAGE_FOLDER_ATTRIBUTE_PATH] = picojson::value(folder.getPath());
o[MESSAGE_FOLDER_ATTRIBUTE_TYPE] =
- picojson::value(MessagingUtil::messageFolderTypeToString(folder->getType()));
- o[MESSAGE_FOLDER_ATTRIBUTE_SYNCHRONIZABLE] = picojson::value(folder->getSynchronizable());
+ picojson::value(MessagingUtil::messageFolderTypeToString(folder.getType()));
+ o[MESSAGE_FOLDER_ATTRIBUTE_SYNCHRONIZABLE] = picojson::value(folder.getSynchronizable());
+ return picojson::value(o);
+}
- picojson::value v(o);
- return v;
+picojson::value MessagingUtil::folderToJson(std::shared_ptr<MessageFolder> folder) {
+ return folderToJson(*folder);
}
PlatformResult MessagingUtil::jsonToMessage(const picojson::value& json,
static picojson::value messageToJson(std::shared_ptr<Message> message);
static picojson::value messageAttachmentToJson(std::shared_ptr<MessageAttachment> attachment);
static picojson::value conversationToJson(std::shared_ptr<MessageConversation> conversation);
+
+ static picojson::value folderToJson(const MessageFolder& folder);
static picojson::value folderToJson(std::shared_ptr<MessageFolder> folder);
+
static common::PlatformResult jsonToMessage(const picojson::value& json,
std::shared_ptr<Message>* result,
MessagingInstance& instance);
};
};
+struct FindFoldersTaskParams {
+ int account_id, callback_id;
+ std::string message_type;
+ MessagingInstance* instance;
+ std::shared_ptr<tizen::AbstractFilter> filter;
+};
+
} // messaging
} // extension
#endif // MESSAGING_MESSAGING_UTIL_H_