--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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 "Connection.h"
+#include "common/logger.h"
+//#include <PlatformException.h>
+#include <cstring>
+#include <email-types.h>
+#include "../message_service.h"
+
+namespace extension {
+namespace messaging {
+namespace DBus {
+
+Connection& Connection::getInstance()
+{
+ LOGD("Entered");
+ static Connection instance;
+ return instance;
+}
+
+GDBusConnection* Connection::getDBus()
+{
+ return m_dbus;
+}
+
+Connection::Connection()
+{
+ dbus_g_thread_init();
+ g_type_init();
+
+ m_dbus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &m_error);
+ if (!m_dbus || m_error) {
+ LOGE("Could not get connection");
+ }
+ LOGD("Connection set");
+}
+
+Connection::~Connection()
+{
+ g_object_unref(m_dbus);
+}
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_DBUS_CONNECTION_H__
+#define __TIZEN_DBUS_CONNECTION_H__
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <gio/gio.h>
+
+namespace extension {
+namespace messaging {
+namespace DBus {
+
+class Connection {
+public:
+ static Connection& getInstance();
+
+ GDBusConnection* getDBus();
+
+private:
+ Connection();
+ Connection(const Connection&);
+ void operator=(const Connection&);
+ virtual ~Connection();
+
+ GDBusConnection* m_dbus;
+ GError* m_error;
+};
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
+
+#endif
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file EmailSignalProxy.cpp
+ */
+
+#include "EmailSignalProxy.h"
+#include "common/logger.h"
+#include <cstring>
+//#include <PlatformException.h>
+
+namespace extension {
+namespace messaging {
+namespace DBus {
+
+EmailSignalProxy::EmailSignalProxy(const std::string& proxy_path,
+ const std::string& proxy_iface) :
+ Proxy (proxy_path,
+ proxy_iface,
+ Proxy::DBUS_NAME_SIGNAL_EMAIL, //specify email signal details
+ DBUS_PATH_NETWORK_STATUS,
+ DBUS_IFACE_NETWORK_STATUS)
+{
+}
+
+EmailSignalProxy::~EmailSignalProxy()
+{
+
+}
+
+void EmailSignalProxy::signalCallback(GDBusConnection* connection,
+ const gchar* sender_name,
+ const gchar* object_path,
+ const gchar* interface_name,
+ const gchar* signal_name,
+ GVariant* parameters)
+{
+ int status, mail_id, op_handle, error_code;
+ char* source = NULL;
+
+ try {
+ g_variant_get(parameters, "(iisii)",
+ &status,
+ &mail_id,
+ &source,
+ &op_handle,
+ &error_code);
+
+ //It is better to log this only when subclass is responsible of handling
+ //passed signal (usually determined by status value).
+ //
+ //LOGD("email:\n status: %d\n mail_id: %d\n "
+ // "source: %s\n op_handle: %d\n error_code: %d",
+ // status, mail_id, source, op_handle, error_code);
+
+ handleEmailSignal(status, mail_id, source, op_handle, error_code);
+
+// } catch(const Common::BasePlatformException& exception) {
+// LOGE("Unhandled exception: %s (%s)!", (exception.getName()).c_str(),
+// (exception.getMessage()).c_str());
+ } catch(...) {
+ LOGE("Unhandled exception!");
+ }
+
+ g_free(source);
+}
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file EmailSignalProxy.h
+ */
+
+#ifndef __TIZEN_DBUS_EMAIL_SIGNAL_PROXY_H__
+#define __TIZEN_DBUS_EMAIL_SIGNAL_PROXY_H__
+
+#include "Proxy.h"
+
+namespace extension {
+namespace messaging {
+namespace DBus {
+
+class EmailSignalProxy;
+typedef std::shared_ptr<EmailSignalProxy> EmailSignalProxyPtr;
+
+class EmailSignalProxy : public Proxy {
+public:
+ EmailSignalProxy(const std::string& proxy_path,
+ const std::string& proxy_iface);
+ virtual ~EmailSignalProxy();
+
+protected:
+ /**
+ * Override this method in subclass to handle email signal
+ */
+ virtual void handleEmailSignal(const int status,
+ const int mail_id,
+ const std::string& source,
+ const int op_handle,
+ const int error_code) = 0;
+
+ virtual void signalCallback(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters);
+
+private:
+};
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
+
+#endif // __TIZEN_DBUS_EMAIL_SIGNAL_PROXY_H__
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file LoadAttachmentProxy.cpp
+ */
+
+#include "LoadAttachmentProxy.h"
+#include <Logger.h>
+#include <PlatformException.h>
+#include <cstring>
+#include <email-types.h>
+#include "MessageService.h"
+#include "Message.h"
+#include "MessageBody.h"
+#include "EmailManager.h"
+#include "JSMessageAttachment.h"
+#include <email-api.h>
+#include <JSWebAPIErrorFactory.h>
+
+namespace DeviceAPI {
+namespace Messaging {
+namespace DBus {
+
+/**
+ * This method perform very specified task (see warning comment) so it should not be
+ * visible outside LoadAttachmentProxy class.
+ */
+void updateAttachmentDataWithEmailGetAttachmentData(
+ std::shared_ptr<MessageAttachment> attachment)
+{
+ struct ScopedEmailAttachmentData {
+ ScopedEmailAttachmentData() : data(NULL) { }
+ ~ScopedEmailAttachmentData() {
+ if(data) {
+ email_free_attachment_data(&data, 1);
+ }
+ }
+ email_attachment_data_t* operator->() { return data; }
+ email_attachment_data_t* data;
+ } attachment_data_holder;
+
+ LOGD("attachmentId = %d", attachment->getId());
+
+ /*
+ * WARNING: email_get_attachment_data seems to be getting NOT COMPLETE
+ * email_attachment_data_t object, observed that:
+ * mail_id is 0
+ * account_id is 0
+ * mailbox_id is 0
+ * Thus currently only attachment_path and attachment_mime_type is used!
+ *
+ * To get COMPLETE data please use: Message::convertEmailToMessageAttachment
+ * mtehod which fetches all attachments from specified email.
+ */
+ int err = email_get_attachment_data(attachment->getId(), &attachment_data_holder.data);
+ if (EMAIL_ERROR_NONE != err ||
+ NULL == attachment_data_holder.data) {
+ LOGE("Couldn't get attachment data for attachmentId:%d", attachment->getId());
+ throw Common::UnknownException("Couldn't get attachment.");
+ }
+
+ LOGD("attachment name : %s", attachment_data_holder->attachment_name);
+
+ if(attachment_data_holder->attachment_mime_type) {
+ attachment->setMimeType(attachment_data_holder->attachment_mime_type);
+ }
+
+ bool isSaved = false;
+ if (attachment_data_holder->attachment_path) {
+ LOGD("set attachment path: %s", attachment_data_holder->attachment_path);
+ attachment->setFilePath(attachment_data_holder->attachment_path);
+
+ LOGD("save_status: %d", attachment_data_holder->save_status);
+ LOGD("attachment_size : %d", attachment_data_holder->attachment_size);
+ }
+ isSaved = attachment_data_holder->save_status;
+ attachment->setIsSaved(isSaved);
+}
+
+LoadAttachmentProxy::LoadAttachmentProxy(const std::string& path,
+ const std::string& iface) :
+ EmailSignalProxy(path, iface)
+{
+}
+
+LoadAttachmentProxy::~LoadAttachmentProxy()
+{
+}
+
+void LoadAttachmentProxy::addCallback(MessageAttachmentCallbackData* callbackOwned)
+{
+ if(callbackOwned->getMessageAttachment()) {
+ LOGD("Registered callback for attachment_id: %d mail_id:%d op_handle:%d nth:%d",
+ callbackOwned->getMessageAttachment()->getId(),
+ callbackOwned->getMessageAttachment()->getMessageId(),
+ callbackOwned->getOperationHandle(),
+ callbackOwned->getNth());
+ }
+
+ m_callback_set.insert(callbackOwned);
+}
+
+void LoadAttachmentProxy::removeCallback(MessageAttachmentCallbackData* callback)
+{
+ if(callback->getMessageAttachment()) {
+ LOGD("Removed callback for attachment_id: %d mail_id:%d op_handle:%d nth:%d",
+ callback->getMessageAttachment()->getId(),
+ callback->getMessageAttachment()->getMessageId(),
+ callback->getOperationHandle(),
+ callback->getNth());
+ }
+
+ m_callback_set.erase(callback);
+}
+
+MessageAttachmentCallbackData* LoadAttachmentProxy::findCallback(const int nth,
+ const int mail_id)
+{
+ CallbackSet::iterator it = m_callback_set.begin();
+ for (; it != m_callback_set.end(); ++it) {
+ MessageAttachmentCallbackData* callback = *it;
+ if (nth == callback->getNth() &&
+ mail_id == callback->getMessageAttachment()->getMessageId()) {
+ return callback;
+ }
+ }
+
+ LOGW("Could not find callback with nth: %d and mail_id: %d", nth, mail_id);
+ return NULL;
+}
+
+void LoadAttachmentProxy::handleEmailSignal(const int status,
+ const int mail_id,
+ const std::string& source,
+ const int op_handle,
+ const int error_code)
+{
+ if(NOTI_DOWNLOAD_ATTACH_FINISH != status &&
+ NOTI_DOWNLOAD_ATTACH_FAIL != status) {
+ return;
+ }
+
+ LOGD("received email signal with:\n status: %d\n mail_id: %d\n "
+ "source: %s\n op_handle(nth): %d\n error_code: %d",
+ status, mail_id, source.c_str(), op_handle, error_code);
+
+ MessageAttachmentCallbackData* callback = NULL;
+
+ //It seems that D-Bus signal op_handle is equal to nth in:
+ // int email_download_attachment(int mail_id, int nth, int *handle)
+ // and not handle returned from above call!!
+ const int nth = op_handle;
+
+ try {
+ // From old implementation it looks that op_handle(nth) is is equal to
+ // index (1 based) of attachment inside email thus it is not globally unique!
+ // Therfore we need to test if mail_id match.
+ // For details see old implementation MailSync.cp line 461
+
+ callback = findCallback(nth, mail_id);
+ if(!callback) {
+ //We should not log not found pair since it could be requested by
+ //different application.
+ return;
+ }
+
+ LOGD("Found callback for pair mailId:%d nth:%d", mail_id, nth);
+
+ if(NOTI_DOWNLOAD_ATTACH_FINISH == status) {
+ LOGD("Message attachment downloaded!");
+
+ std::shared_ptr<MessageAttachment> att = callback->getMessageAttachment();
+ updateAttachmentDataWithEmailGetAttachmentData(att);
+ LOGD("Updated Message attachment object");
+
+ try {
+ JSContextRef context = callback->getContext();
+ JSObjectRef jsMessageAtt = JSMessageAttachment::makeJSObject(context, att);
+ callback->callSuccessCallback(jsMessageAtt);
+ } catch (...) {
+ LOGW("Couldn't create JSMessageAttachment object!");
+ throw Common::UnknownException(
+ "Couldn't create JSMessageAttachment object!");
+ }
+
+ } else if(NOTI_DOWNLOAD_ATTACH_FAIL) {
+ LOGD("Load message attachment failed!");
+ JSObjectRef errobj = Common::JSWebAPIErrorFactory::makeErrorObject(
+ callback->getContext(),
+ callback->getErrorName(),
+ callback->getErrorMessage());
+ callback->callErrorCallback(errobj);
+ }
+ } catch (const Common::BasePlatformException& e) {
+ LOGE("Exception in signal callback");
+ JSObjectRef errobj = Common::JSWebAPIErrorFactory::makeErrorObject(
+ callback->getContext(), e);
+ callback->callErrorCallback(errobj);
+ } catch (...) {
+ LOGE("Exception in signal callback");
+ JSObjectRef errobj = Common::JSWebAPIErrorFactory::makeErrorObject(
+ callback->getContext(),
+ Common::JSWebAPIErrorFactory::UNKNOWN_ERROR,
+ "Handling signal callback failed");
+ callback->callErrorCallback(errobj);
+ }
+
+ if(callback) {
+ removeCallback(callback);
+ delete callback;
+ }
+}
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file LoadAttachmentProxy.h
+ */
+
+#ifndef __TIZEN_DBUS_LOAD_ATTACHMENT_PROXY_H__
+#define __TIZEN_DBUS_LOAD_ATTACHMENT_PROXY_H__
+
+#include "EmailSignalProxy.h"
+#include <set>
+
+namespace DeviceAPI {
+namespace Messaging {
+
+class MessageAttachmentCallbackData;
+
+namespace DBus {
+
+class LoadAttachmentProxy;
+typedef std::shared_ptr<LoadAttachmentProxy> LoadAttachmentProxyPtr;
+
+class LoadAttachmentProxy : public EmailSignalProxy {
+public:
+
+ // Callback is owned by this set
+ typedef std::set<MessageAttachmentCallbackData*> CallbackSet;
+
+ LoadAttachmentProxy(const std::string& path,
+ const std::string& iface);
+ virtual ~LoadAttachmentProxy();
+
+ //Passed callback will be owned by this proxy
+ void addCallback(MessageAttachmentCallbackData* callbackOwned);
+ void removeCallback(MessageAttachmentCallbackData* callback);
+
+protected:
+ virtual void handleEmailSignal(const int status,
+ const int mail_id,
+ const std::string& source,
+ const int op_handle,
+ const int error_code);
+
+private:
+ MessageAttachmentCallbackData* findCallback(const int nth, const int mail_id);
+
+ CallbackSet m_callback_set;
+};
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
+
+#endif // __TIZEN_DBUS_LOAD_ATTACHMENT_PROXY_H__
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file LoadBodyProxy.cpp
+ */
+
+#include "LoadBodyProxy.h"
+#include <Logger.h>
+#include <PlatformException.h>
+#include <cstring>
+#include <email-types.h>
+#include "MessageService.h"
+#include "Message.h"
+#include "MessageBody.h"
+#include "EmailManager.h"
+#include "JSMessage.h"
+#include <JSWebAPIErrorFactory.h>
+
+namespace DeviceAPI {
+namespace Messaging {
+namespace DBus {
+
+LoadBodyProxy::LoadBodyProxy(const std::string& path,
+ const std::string& iface) :
+ EmailSignalProxy(path, iface)
+{
+
+}
+
+LoadBodyProxy::~LoadBodyProxy()
+{
+
+}
+
+void LoadBodyProxy::addCallback(MessageBodyCallbackData* callbackOwned)
+{
+ m_callback_set.insert(callbackOwned);
+}
+
+void LoadBodyProxy::removeCallback(MessageBodyCallbackData* callback)
+{
+ m_callback_set.erase(callback);
+}
+
+MessageBodyCallbackData* LoadBodyProxy::findCallbackByOpHandle(const int op_handle)
+{
+ CallbackSet::iterator it = m_callback_set.begin();
+ for (; it != m_callback_set.end(); ++it) {
+
+ MessageBodyCallbackData* callback = *it;
+ if (op_handle == callback->getOperationHandle()) {
+ return callback;
+ }
+ }
+
+ LOGW("Could not find callback with op_handle: %d", op_handle);
+ return NULL;
+}
+
+void LoadBodyProxy::handleEmailSignal(const int status,
+ const int mail_id,
+ const std::string& source,
+ const int op_handle,
+ const int error_code)
+{
+ switch(status) {
+ //We should handle this signal since it is DOWNLOAD_BODY_*
+ case NOTI_DOWNLOAD_BODY_START:
+ case NOTI_DOWNLOAD_BODY_FINISH:
+ case NOTI_DOWNLOAD_BODY_FAIL: {
+ } break;
+
+ // This values have not been explicitly handled in old implementation
+ // NOTI_DOWNLOAD_BODY_CANCEL
+ // NOTI_DOWNLOAD_MULTIPART_BODY
+ //
+ // 1. I assume that NOTI_DOWNLOAD_MULTIPART_BODY is called several times
+ // before final NOTI_DOWNLOAD_BODY_FINISH is called, thus we should not
+ // remove nor delete callback.
+ //
+ // 2. I assume that NOTI_DOWNLOAD_BODY_CANCEL is called before
+ // NOTI_DOWNLOAD_BODY_FAIL so we should do the same as in point 1.
+ case NOTI_DOWNLOAD_BODY_CANCEL:
+ case NOTI_DOWNLOAD_MULTIPART_BODY:
+ default: {
+ // This signal is not related with load message body or there is nothing
+ // to do so we can return now.
+ return;
+ } break;
+ }
+
+ LOGD("received email signal with:\n status: %d\n mail_id: %d\n "
+ "source: %s\n op_handle: %d\n error_code: %d",
+ status, mail_id, source.c_str(), op_handle, error_code);
+
+ if(NOTI_DOWNLOAD_BODY_START == status) {
+ LOGD("Download message body started ...");
+ // There is nothing more to do so we can return now.
+ return;
+ }
+
+ MessageBodyCallbackData* callback = NULL;
+ try {
+ callback = findCallbackByOpHandle(op_handle);
+ if (!callback) {
+ LOGE("Callback is null");
+ } else {
+ if( (NOTI_DOWNLOAD_BODY_FINISH == status) ||
+ (NOTI_DOWNLOAD_BODY_FAIL == status &&
+ EMAIL_ERROR_MAIL_IS_ALREADY_DOWNLOADED == error_code)) {
+
+ // Old implementation is not verifying whether message update failed,
+ // it just calls success callback.
+ if(callback->getMessage()) {
+ email_mail_data_t* mail_data = EmailManager::loadMessage(
+ callback->getMessage()->getId());
+ if (mail_data) {
+ callback->getMessage()->updateEmailMessage(*mail_data);
+ EmailManager::freeMessage(mail_data);
+ mail_data = NULL;
+ }
+
+ //TODO: this should be reviewed when attachments and
+ // loadAttachments have been completed.
+ //TODO: see old implementation lines 608-635 in MailSync.cpp
+ /*
+ * This is original Messaging implementation:
+ *
+ * std::vector<IAttachmentPtr> attachments = mail->getAttachments();
+ * std::vector<IAttachmentPtr> inlineAttachments = mail->getInlineAttachments();
+ *
+ * for (unsigned int idx = 0; idx < attachments.size() ; idx++ )
+ * {
+ * LoggerD("set Attachment ID = " << attachments[idx]->getAttachmentID());
+ * attachments[idx]->setMessage(event->m_message);
+ *
+ * }
+ * for (unsigned int idx = 0; idx < inlineAttachments.size() ; idx++ )
+ * {
+ * LoggerD("set inline Attachment ID = " << inlineAttachments[idx]->getAttachmentID());
+ * inlineAttachments[idx]->setMessage(event->m_message);
+ * }
+ */
+ }
+
+ LOGD("Message body downloaded!");
+ try {
+ JSContextRef context = callback->getContext();
+ JSObjectRef jsMessage = JSMessage::makeJSObject(context,
+ callback->getMessage());
+ callback->callSuccessCallback(jsMessage);
+ } catch (...) {
+ LOGW("Couldn't create JSMessage object!");
+ throw Common::UnknownException(
+ "Couldn't create JSMessage object!");
+ }
+
+ } else if(NOTI_DOWNLOAD_BODY_FAIL == status) {
+ LOGD("Load message body failed!");
+ JSObjectRef errobj = Common::JSWebAPIErrorFactory::makeErrorObject(
+ callback->getContext(),
+ callback->getErrorName(),
+ callback->getErrorMessage());
+ callback->callErrorCallback(errobj);
+ }
+ }
+ }
+ catch (const Common::BasePlatformException& e) {
+ LOGE("Exception in signal callback");
+ JSObjectRef errobj = Common::JSWebAPIErrorFactory::makeErrorObject(
+ callback->getContext(), e);
+ callback->callErrorCallback(errobj);
+ }
+ catch (...) {
+ LOGE("Exception in signal callback");
+ JSObjectRef errobj = Common::JSWebAPIErrorFactory::makeErrorObject(
+ callback->getContext(),
+ Common::JSWebAPIErrorFactory::UNKNOWN_ERROR,
+ "Handling signal callback failed");
+ callback->callErrorCallback(errobj);
+ }
+
+ if(callback) {
+ removeCallback(callback);
+ delete callback;
+ }
+}
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file LoadBodyProxy.h
+ */
+
+#ifndef __TIZEN_DBUS_LOAD_BODY_PROXY_H__
+#define __TIZEN_DBUS_LOAD_BODY_PROXY_H__
+
+#include "EmailSignalProxy.h"
+#include <set>
+
+namespace DeviceAPI {
+namespace Messaging {
+
+class MessageBodyCallbackData;
+
+namespace DBus {
+
+class LoadBodyProxy;
+typedef std::shared_ptr<LoadBodyProxy> LoadBodyProxyPtr;
+
+class LoadBodyProxy : public EmailSignalProxy {
+public:
+
+ // Callback is owned by this set
+ typedef std::set<MessageBodyCallbackData*> CallbackSet;
+
+ LoadBodyProxy(const std::string& path,
+ const std::string& iface);
+ virtual ~LoadBodyProxy();
+
+ //Passed callback will be owned by this proxy
+ void addCallback(MessageBodyCallbackData* callbackOwned);
+ void removeCallback(MessageBodyCallbackData* callback);
+
+protected:
+ virtual void handleEmailSignal(const int status,
+ const int mail_id,
+ const std::string& source,
+ const int op_handle,
+ const int error_code);
+
+private:
+ /**
+ * Find callback by operation handle returned from:
+ * int email_download_body(..., int *handle);
+ */
+ MessageBodyCallbackData* findCallbackByOpHandle(const int op_handle);
+
+ CallbackSet m_callback_set;
+};
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
+
+#endif // __TIZEN_DBUS_LOAD_BODY_PROXY_H__
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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 "MessageProxy.h"
+#include "Connection.h"
+#include <Logger.h>
+#include <Message.h>
+#include <MessageEmail.h>
+#include <MessageConversation.h>
+#include <MessageFolder.h>
+#include <ChangeListenerContainer.h>
+#include <EmailManager.h>
+#include <PlatformException.h>
+
+namespace DeviceAPI {
+namespace Messaging {
+namespace DBus {
+
+MessageProxy::MessageProxy():
+ Proxy(Proxy::DBUS_PATH_EMAIL_STORAGE_CHANGE,
+ Proxy::DBUS_IFACE_EMAIL_STORAGE_CHANGE,
+ Proxy::DBUS_NAME_SIGNAL_EMAIL,
+ Proxy::DBUS_PATH_EMAIL_STORAGE_CHANGE,
+ Proxy::DBUS_IFACE_EMAIL_STORAGE_CHANGE)
+{
+}
+
+MessageProxy::~MessageProxy()
+{
+}
+
+void MessageProxy::signalCallback(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters)
+{
+ LOGD("Enter");
+ int status, account_id, object_id, thread_id;
+ char* name;
+ g_variant_get(parameters, "(iiisi)",
+ &status,
+ &account_id,
+ &object_id,
+ &name,
+ &thread_id);
+ LOGD("status: %d", status);
+ LOGD("account_id: %d", account_id);
+ LOGD("object_id: %d", object_id);
+ LOGD("name: %s", name);
+ LOGD("thread_id: %d", thread_id);
+
+ try {
+ switch (status) {
+ case NOTI_MAIL_ADD:
+ case NOTI_MAIL_UPDATE:
+ handleEmailEvent(account_id, object_id, thread_id, status);
+ break;
+ case NOTI_MAIL_DELETE:
+ //ids of removing messages are sent with name in format:
+ //id1,id2,id3,
+ handleEmailRemoveEvent(account_id, name);
+ break;
+ case NOTI_MAIL_DELETE_FINISH:
+ case NOTI_MAIL_DELETE_FAIL:
+ //notify EmailManager, maybe it tries to delete mail
+ notifyEmailManager(name, static_cast<email_noti_on_storage_event>(status));
+ break;
+ case NOTI_THREAD_DELETE:
+ handleThreadRemoveEvent(account_id, object_id);
+ break;
+ case NOTI_MAILBOX_ADD:
+ case NOTI_MAILBOX_UPDATE:
+ case NOTI_MAILBOX_FIELD_UPDATE:
+ case NOTI_MAILBOX_RENAME:
+ case NOTI_MAILBOX_DELETE:
+ handleMailboxEvent(account_id, object_id, status);
+ break;
+ default:
+ LOGD("Unrecognized status: %d", status);
+ }
+ } catch (const Common::BasePlatformException& err) {
+ LOGE("%s (%s)", (err.getName()).c_str(), (err.getMessage()).c_str());
+ } catch (...) {
+ LOGE("Failed to call callback");
+ }
+ g_free(name);
+}
+
+void MessageProxy::handleEmailEvent(int account_id, int mail_id, int thread_id, int event)
+{
+ LOGD("Enter");
+
+ if(NOTI_MAIL_UPDATE == event) {
+ //getting thread_id from message
+ email_mail_data_t *mail_data = NULL;
+
+ if(EMAIL_ERROR_NONE != email_get_mail_data(mail_id, &mail_data)) {
+ if (mail_data) email_free_mail_data(&mail_data, 1);
+
+ LOGE("Failed to get mail data during setting conversation id in MessageProxy.");
+ return;
+ }
+
+ thread_id = mail_data->thread_id;
+
+ if(EMAIL_ERROR_NONE != email_free_mail_data(&mail_data,1)) {
+ LOGE("Failed to free mail data memory");
+ }
+ }
+
+ email_mail_data_t* mail_data = EmailManager::getInstance().loadMessage(mail_id);
+ if (mail_data == NULL) {
+ throw Common::UnknownException("Failed to load email");
+ }
+ std::shared_ptr<Message> msg = Message::convertPlatformEmailToObject(*mail_data);
+ ConversationPtr conv = MessageConversation::convertEmailConversationToObject(
+ thread_id);
+
+ EventMessages* eventMsg = new EventMessages();
+ eventMsg->service_type = MessageType::EMAIL;
+ eventMsg->service_id = account_id;
+ eventMsg->items.push_back(msg);
+ EventConversations* eventConv = new EventConversations();
+ eventConv->service_type = MessageType::EMAIL;
+ eventConv->service_id = account_id;
+ eventConv->items.push_back(conv);
+ switch (event) {
+ case NOTI_MAIL_ADD:
+ ChangeListenerContainer::getInstance().callMessageAdded(eventMsg);
+ if (conv->getMessageCount() == 1) {
+ LOGD("This thread is new, triggering conversationAdded");
+ ChangeListenerContainer::getInstance().callConversationAdded(eventConv);
+ } else {
+ LOGD("This thread is not new, but it's updated");
+ ChangeListenerContainer::getInstance().callConversationUpdated(eventConv);
+ }
+ break;
+ case NOTI_MAIL_UPDATE:
+ ChangeListenerContainer::getInstance().callMessageUpdated(eventMsg);
+ ChangeListenerContainer::getInstance().callConversationUpdated(eventConv);
+ break;
+ default:
+ LOGW("Unknown event type: %d", event);
+ break;
+
+ }
+ delete eventMsg;
+ delete eventConv;
+
+ EmailManager::getInstance().freeMessage(mail_data);
+}
+
+std::vector<int> getMailIds(const std::string& idsString)
+{
+ std::stringstream idsStream(idsString);
+ std::string item;
+ std::vector<int> ids;
+ while (std::getline(idsStream, item, ',')) {
+ if (item.length() > 0) {
+ int id;
+ std::stringstream stream(item);
+ stream >> id;
+ if (stream) {
+ LOGD("Mail delete id: %d", id);
+ ids.push_back(id);
+ }
+ }
+ }
+ return ids;
+}
+
+void MessageProxy::handleEmailRemoveEvent(int account_id, const std::string& idsString)
+{
+ LOGD("Enter");
+ std::vector<int> ids = getMailIds(idsString);
+ if (ids.empty()) {
+ LOGD("Mail id list is empty.");
+ return;
+ }
+ EventMessages* eventMsg = new EventMessages();
+ eventMsg->service_type = MessageType::EMAIL;
+ eventMsg->service_id = account_id;
+ for (auto it = ids.begin(); it != ids.end(); ++it) {
+ //it turns out that this event is triggered after messages are removed
+ //so we just create empty messages with id and type
+ std::shared_ptr<Message> msg = std::make_shared<MessageEmail>();
+ msg->setId(*it);
+ eventMsg->items.push_back(msg);
+ }
+ ChangeListenerContainer::getInstance().callMessageRemoved(eventMsg);
+ delete eventMsg;
+ eventMsg = NULL;
+}
+
+void MessageProxy::notifyEmailManager(const std::string& idsString,
+ email_noti_on_storage_event status)
+{
+ LOGD("Enter");
+ std::vector<int> ids = getMailIds(idsString);
+ if (ids.empty()) {
+ LOGD("Mail id list is empty.");
+ return;
+ }
+ EmailManager::getInstance().removeStatusCallback(ids, status);
+}
+
+void MessageProxy::handleThreadRemoveEvent(int account_id, int thread_id)
+{
+ LOGD("Enter");
+ //event is called after thread is removed, so we just set thread id
+ ConversationPtr conv = std::make_shared<MessageConversation>();
+ conv->setConversationId(thread_id);
+
+ EventConversations* eventConv = new EventConversations();
+ eventConv->service_type = MessageType::EMAIL;
+ eventConv->service_id = account_id;
+ eventConv->items.push_back(conv);
+ ChangeListenerContainer::getInstance().callConversationRemoved(eventConv);
+ delete eventConv;
+ eventConv = NULL;
+}
+
+void MessageProxy::handleMailboxEvent(int account_id, int mailbox_id, int event)
+{
+ LOGD("Enter");
+
+ EventFolders* eventFolder = new EventFolders();
+ eventFolder->service_type = MessageType::EMAIL;
+ eventFolder->service_id = account_id;
+ FolderPtr folder;
+ if (event == NOTI_MAILBOX_DELETE) {
+ //this event is triggered after mailbox is removed
+ //so we just create folder with id
+ folder.reset(new MessageFolder(std::to_string(mailbox_id),
+ "", //parent_id
+ "", //service_id
+ "", //content_type
+ "", //name
+ "", //path
+ MessageFolderType::MESSAGE_FOLDER_TYPE_NOTSTANDARD,
+ false));
+ } else {
+ email_mailbox_t* mail_box = NULL;
+ if (EMAIL_ERROR_NONE != email_get_mailbox_by_mailbox_id(mailbox_id, &mail_box)) {
+ LOGE("Mailbox not retrieved");
+ delete eventFolder;
+ throw Common::UnknownException("Failed to load mailbox");
+ }
+ folder.reset(new MessageFolder(*mail_box));
+ if (EMAIL_ERROR_NONE != email_free_mailbox(&mail_box, 1)) {
+ LOGD("Failed to free email_free_mailbox");
+ }
+ }
+ eventFolder->items.push_back(folder);
+ switch (event) {
+ case NOTI_MAILBOX_ADD:
+ ChangeListenerContainer::getInstance().callFolderAdded(eventFolder);
+ break;
+ case NOTI_MAILBOX_UPDATE:
+ case NOTI_MAILBOX_FIELD_UPDATE:
+ ChangeListenerContainer::getInstance().callFolderUpdated(eventFolder);
+ break;
+ case NOTI_MAILBOX_DELETE:
+ ChangeListenerContainer::getInstance().callFolderRemoved(eventFolder);
+ break;
+ default:
+ LOGW("Unknown event type: %d", event);
+ }
+ delete eventFolder;
+}
+
+} //DBus
+} //Messaging
+} //DeviceAPI
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_MESSAGE_PROXY_H
+#define __TIZEN_MESSAGE_PROXY_H
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <gio/gio.h>
+#include <memory>
+#include <string>
+#include <email-types.h>
+#include "Proxy.h"
+
+namespace DeviceAPI {
+namespace Messaging {
+namespace DBus {
+
+class MessageProxy: public Proxy {
+public:
+ MessageProxy();
+ virtual ~MessageProxy();
+protected:
+ virtual void signalCallback(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters);
+ /**
+ * Handles e-mail add and update only.
+ * @param account_id
+ * @param mail_id
+ * @param thread_id
+ * @param event
+ */
+ void handleEmailEvent(int account_id, int mail_id, int thread_id, int event);
+ void handleEmailRemoveEvent(int account_id, const std::string& idsString);
+ void notifyEmailManager(const std::string& idsString, email_noti_on_storage_event status);
+ void handleThreadRemoveEvent(int account_id, int thread_id);
+ void handleMailboxEvent(int account_id, int mailbox_id, int event);
+};
+
+typedef std::shared_ptr<MessageProxy> MessageProxyPtr;
+
+} //DBus
+} //Messaging
+} //DeviceAPI
+
+#endif /* __TIZEN_MESSAGE_PROXY_H */
+
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file Proxy.cpp
+ */
+
+#include "Proxy.h"
+#include "common/logger.h"
+//#include <PlatformException.h>
+#include <cstring>
+#include <email-types.h>
+#include "../message_service.h"
+
+namespace extension {
+namespace messaging {
+namespace DBus {
+
+const char* Proxy::DBUS_PATH_NETWORK_STATUS = "/User/Email/NetworkStatus";
+const char* Proxy::DBUS_IFACE_NETWORK_STATUS = "User.Email.NetworkStatus";
+const char* Proxy::DBUS_PATH_EMAIL_STORAGE_CHANGE = "/User/Email/StorageChange";
+const char* Proxy::DBUS_IFACE_EMAIL_STORAGE_CHANGE = "User.Email.StorageChange";
+const char* Proxy::DBUS_NAME_SIGNAL_EMAIL = "email";
+
+Proxy::Proxy(const std::string& proxy_path,
+ const std::string& proxy_iface,
+ const std::string& signal_name,
+ const std::string& signal_path,
+ const std::string& signal_iface) :
+ m_conn(Connection::getInstance()),
+ m_sub_id(0),
+ m_path(proxy_path),
+ m_iface(proxy_iface),
+ m_signal_name(signal_name),
+ m_signal_path(signal_path),
+ m_signal_iface(signal_iface),
+ m_error(NULL),
+ m_dbus_signal_subscribed(false)
+{
+ LOGD("Proxy:\n"
+ " proxy_path: %s\n proxy_iface: %s"
+ " signal_name: %s\n signal_path:%s\n signal_iface:%s",
+ m_path.c_str(), m_iface.c_str(),
+ m_signal_name.c_str(), m_signal_path.c_str(), m_signal_iface.c_str());
+
+ const gchar* unique_name = g_dbus_connection_get_unique_name(m_conn.getDBus());
+ LOGD("Generated unique name: %d", unique_name);
+
+ // path and interface are not obligatory to receive, but
+ // they should be set to send the signals.
+ m_proxy = g_dbus_proxy_new_sync(m_conn.getDBus(),
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
+ NULL, unique_name, m_path.c_str(), m_iface.c_str(), NULL, &m_error);
+ if (!m_proxy || m_error) {
+ LOGE("Could not get proxy");
+ //TODO throw Common::UnknownException("Could not get proxy");
+ }
+}
+
+Proxy::~Proxy()
+{
+ signalUnsubscribe();
+}
+
+void Proxy::signalCallbackProxy(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ Proxy* this_ptr = static_cast<Proxy*>(user_data);
+ if (!this_ptr) {
+ LOGW("Proxy is null, nothing to do");
+ return;
+ }
+
+ try {
+ //It is better to log this only when subclass is responsible of handling
+ //passed signal. If you need it put it into your signalCallback(...) method
+ //LOGD("signal: %s from: %s path: %s interface: %s",
+ // signal_name, sender_name, object_path, interface_name);
+
+ this_ptr->signalCallback(connection, sender_name, object_path, interface_name,
+ signal_name, parameters);
+
+// } catch(const Common::BasePlatformException& exception) {
+// LOGE("Unhandled exception: %s (%s)!", (exception.getName()).c_str(),
+// (exception.getMessage()).c_str());
+ } catch(...) {
+ LOGE("Unhandled exception!");
+ }
+}
+
+void Proxy::signalSubscribe()
+{
+ if(m_dbus_signal_subscribed) {
+ LOGW("Proxy has already subscribed for listening DBus signal");
+ return;
+ }
+
+ const char* sender = NULL;
+ m_sub_id = g_dbus_connection_signal_subscribe(m_conn.getDBus(),
+ sender,
+ m_signal_iface.c_str(),
+ m_signal_name.c_str(),
+ m_signal_path.c_str(),
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ signalCallbackProxy,
+ static_cast<gpointer>(this),
+ NULL);
+ LOGD("g_dbus_connection_signal_subscribe returned id: %d", m_sub_id);
+
+ m_dbus_signal_subscribed = true;
+}
+
+void Proxy::signalUnsubscribe()
+{
+ if (!m_dbus_signal_subscribed) {
+ LOGW("Proxy hasn't subscribed for listening DBus signal");
+ return;
+ }
+
+ g_dbus_connection_signal_unsubscribe(m_conn.getDBus(), m_sub_id);
+ LOGD("g_dbus_connection_signal_unsubscribe finished");
+
+ m_dbus_signal_subscribed = false;
+}
+
+const std::string& Proxy::getSignalName() const
+{
+ return m_signal_name;
+}
+
+const std::string& Proxy::getSignalPath() const
+{
+ return m_signal_path;
+}
+
+const std::string& Proxy::getSignalInterfaceName() const
+{
+ return m_signal_iface;
+}
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file Proxy.h
+ */
+
+#ifndef __TIZEN_DBUS_PROXY_H__
+#define __TIZEN_DBUS_PROXY_H__
+
+#include "Connection.h"
+#include <memory>
+#include <string>
+#include <mutex>
+#include <map>
+#include "common/callback_user_data.h"
+
+namespace extension {
+namespace messaging {
+namespace DBus {
+
+
+class Proxy;
+typedef std::shared_ptr<Proxy> ProxyPtr;
+
+/**
+ * This is generic dbus signal listener proxy.
+ */
+class Proxy {
+public:
+ /**
+ * List of Tizen path and interface names:
+ */
+ static const char* DBUS_PATH_NETWORK_STATUS;
+ static const char* DBUS_IFACE_NETWORK_STATUS;
+ static const char* DBUS_PATH_EMAIL_STORAGE_CHANGE;
+ static const char* DBUS_IFACE_EMAIL_STORAGE_CHANGE;
+ /**
+ * Name of email signal
+ */
+ static const char* DBUS_NAME_SIGNAL_EMAIL;
+
+ /**
+ * @param proxy_path - path of this proxy
+ * @param proxy_iface - interface name of this proxy
+ *
+ * @param signal_name - expected signal name
+ * @param signal_path - expected signal path
+ * @param signal_iface - expected signal interface name
+ */
+ Proxy(const std::string& proxy_path,
+ const std::string& proxy_iface,
+ const std::string& signal_name,
+ const std::string& signal_path,
+ const std::string& signal_iface);
+
+ virtual ~Proxy();
+
+ void signalSubscribe();
+ void signalUnsubscribe();
+
+ const std::string& getSignalName() const;
+ const std::string& getSignalPath() const;
+ const std::string& getSignalInterfaceName() const;
+
+protected:
+ /**
+ * Please implement this method in subclass to handle signal.
+ * Executed by static void signalCallbackProxy(...).
+ */
+ virtual void signalCallback(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters) = 0;
+
+private:
+ /**
+ * This method (registered with g_dbus_connection_signal_subscribe) is executed by
+ * DBus when signal is received. It calls
+ * (static_cast<Proxy*>(user_data))->signalCallback(...)
+ */
+ static void signalCallbackProxy(GDBusConnection *connection,
+ const gchar *sender_name,
+ const gchar *object_path,
+ const gchar *interface_name,
+ const gchar *signal_name,
+ GVariant *parameters,
+ gpointer user_data);
+
+ Connection& m_conn;
+ guint m_sub_id;
+
+ std::string m_path;
+ std::string m_iface;
+
+ std::string m_signal_name;
+ std::string m_signal_path;
+ std::string m_signal_iface;
+
+ GError* m_error;
+ GDBusProxy* m_proxy;
+ bool m_dbus_signal_subscribed;
+};
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
+
+#endif // __TIZEN_DBUS_PROXY_H__
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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 "SendProxy.h"
+
+#include <Logger.h>
+#include <email-types.h>
+#include <EmailManager.h>
+
+namespace DeviceAPI {
+namespace Messaging {
+namespace DBus {
+
+SendProxy::SendProxy():
+ EmailSignalProxy(Proxy::DBUS_PATH_NETWORK_STATUS,
+ Proxy::DBUS_IFACE_NETWORK_STATUS)
+{
+}
+
+SendProxy::~SendProxy()
+{
+}
+
+void SendProxy::handleEmailSignal(const int status,
+ const int account_id,
+ const std::string& source,
+ const int mail_id,
+ const int error_code)
+{
+ LOGD("Enter");
+ switch (status) {
+ case NOTI_SEND_FINISH:
+ case NOTI_SEND_FAIL:
+ LOGD("Recognized status for email send");
+ LOGD("received email signal with:\n status: %d\n account_id: %d\n "
+ "source: %s\n mail_id: %d\n error_code: %d",
+ status, account_id, source.c_str(), mail_id, error_code);
+ EmailManager::getInstance().sendStatusCallback(mail_id,
+ static_cast<email_noti_on_network_event>(status),
+ error_code);
+ break;
+ default:
+ LOGD("Unrecognized status %d, ignoring", status);
+ }
+}
+
+
+} //DBus
+} //Messaging
+} //DeviceAPI
\ No newline at end of file
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+#ifndef __TIZEN_SEND_PROXY_H
+#define __TIZEN_SEND_PROXY_H
+
+#include "EmailSignalProxy.h"
+
+namespace DeviceAPI {
+namespace Messaging {
+namespace DBus {
+
+class SendProxy: public EmailSignalProxy {
+public:
+ SendProxy();
+ virtual ~SendProxy();
+protected:
+ virtual void handleEmailSignal(const int status,
+ const int account_id,
+ const std::string& source,
+ const int op_handle,
+ const int error_code);
+
+};
+
+typedef std::shared_ptr<SendProxy> SendProxyPtr;
+
+} //DBus
+} //Messaging
+} //DeviceAPI
+
+#endif /* __TIZEN_SEND_PROXY_H */
+
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file SyncProxy.cpp
+ */
+
+#include "SyncProxy.h"
+#include "common/logger.h"
+//#include <PlatformException.h>
+#include <cstring>
+#include <email-types.h>
+#include "../message_service.h"
+
+namespace extension {
+namespace messaging {
+namespace DBus {
+
+SyncProxy::SyncProxy(const std::string& path,
+ const std::string& iface) :
+ EmailSignalProxy(path, iface)
+{
+
+}
+
+SyncProxy::~SyncProxy()
+{
+
+}
+
+void SyncProxy::addCallback(long op_id, common::CallbackUserData* callbackOwned)
+{
+ m_callback_map.insert(std::make_pair(op_id, callbackOwned));
+}
+
+common::CallbackUserData* SyncProxy::getCallback(long op_id)
+{
+ common::CallbackUserData* cb = NULL;
+ CallbackMap::iterator it = m_callback_map.find(op_id);
+ if (it != m_callback_map.end()) {
+ cb = it->second;
+ return cb;
+ }
+ LOGE("Could not find callback");
+ //TODO throw Common::UnknownException("Could not find callback");
+ return cb;
+}
+
+void SyncProxy::removeCallback(long op_id){
+ CallbackMap::iterator it = m_callback_map.find(op_id);
+ if (it != m_callback_map.end()) {
+ common::CallbackUserData* cb = it->second;
+ delete cb;
+ cb = NULL;
+ m_callback_map.erase(it);
+ }
+ else {
+ LOGE("Could not find callback");
+ //TODO throw Common::UnknownException("Could not find callback");
+ }
+}
+
+void SyncProxy::handleEmailSignal(const int status,
+ const int mail_id,
+ const std::string& source,
+ const int op_handle,
+ const int error_code)
+{
+ if( NOTI_DOWNLOAD_START != status &&
+ NOTI_DOWNLOAD_FINISH != status &&
+ NOTI_DOWNLOAD_FAIL != status ) {
+ // Nothing to do: this status is not related to sync nor syncFolder request
+ return;
+ }
+
+ LOGD("received email signal with:\n status: %d\n mail_id: %d\n "
+ "source: %s\n op_handle: %d\n error_code: %d",
+ status, mail_id, source.c_str(), op_handle, error_code);
+
+ if (NOTI_DOWNLOAD_START == status) {
+ LOGD("Sync started...");
+ // There is nothing more to do so we can return now.
+ return;
+ }
+
+ common::CallbackUserData* callback = NULL;
+ CallbackMap::iterator callback_it;
+
+ try {
+ callback_it = findSyncCallbackByOpHandle(op_handle);
+ callback = callback_it->second;
+ if (!callback) {
+ LOGE("Callback is null");
+ //TODO throw Common::UnknownException("Callback is null");
+ }
+
+ switch (status) {
+ case NOTI_DOWNLOAD_FINISH:
+ LoggerD("Sync finished!");
+ //TODO callback->callSuccessCallback();
+ break;
+
+ case NOTI_DOWNLOAD_FAIL:
+ LoggerD("Sync failed!");
+ //TODO callback->callErrorCallback();
+ break;
+
+ default:
+ break;
+ }
+ }
+// catch (const Common::BasePlatformException& e) {
+// // this situation may occur when there is no callback in the
+// // map with specified opId (for example stopSync() has
+// // removed it), but sync() was already started - only
+// // warning here:
+// LOGE("Exception in signal callback");
+// }
+ catch(...)
+ {
+ LOGE("Exception in signal callback");
+ }
+
+ if(callback) {
+ delete callback;
+ m_callback_map.erase(callback_it);
+ }
+}
+
+SyncProxy::CallbackMap::iterator SyncProxy::findSyncCallbackByOpHandle(
+ const int op_handle)
+{
+ CallbackMap::iterator it = m_callback_map.begin();
+ for (; it != m_callback_map.end(); ++it) {
+ SyncCallbackData* cb = dynamic_cast<SyncCallbackData*>(it->second);
+ if (!cb) continue;
+
+ if (op_handle == cb->getOperationHandle()) {
+ return it;
+ }
+ }
+ // this situation may occur when there is no callback in the
+ // map with specified opId (for example stopSync() has
+ // removed it), but sync() was already started - only
+ // warning here:
+ LOGW("Could not find callback with op_handle: %d", op_handle);
+ //TODO throw Common::UnknownException("Could not find callback");
+}
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// 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.
+//
+
+/**
+ * @file SyncProxy.h
+ */
+
+#ifndef __TIZEN_DBUS_SYNC_PROXY_H__
+#define __TIZEN_DBUS_SYNC_PROXY_H__
+
+#include "EmailSignalProxy.h"
+
+namespace extension {
+namespace messaging {
+namespace DBus {
+
+class SyncProxy;
+typedef std::shared_ptr<SyncProxy> SyncProxyPtr;
+
+class SyncProxy : public EmailSignalProxy {
+public:
+
+ // Callback is owned by this map
+ typedef std::map<long, common::CallbackUserData*> CallbackMap;
+
+ SyncProxy(const std::string& path,
+ const std::string& iface);
+ virtual ~SyncProxy();
+
+ //Passed callback will be owned by this proxy
+ void addCallback(long op_id, common::CallbackUserData* callbackOwned);
+ common::CallbackUserData* getCallback(long op_id);
+ void removeCallback(long op_id);
+
+protected:
+ virtual void handleEmailSignal(const int status,
+ const int mail_id,
+ const std::string& source,
+ const int op_handle,
+ const int error_code);
+
+private:
+ /**
+ * Find callback by operation handle returned from:
+ * int email_sync_header(..., int *handle);
+ */
+ CallbackMap::iterator findSyncCallbackByOpHandle(const int op_handle);
+
+ CallbackMap m_callback_map;
+};
+
+} //namespace DBus
+} //namespace Messaging
+} //namespace DeviceAPI
+
+#endif // __TIZEN_DBUS_SYNC_PROXY_H__
EmailManager& EmailManager::getInstance()
{
- LOGD("Entered");
+ LoggerD("Entered");
static EmailManager instance;
return instance;
EmailManager::EmailManager()
{
- LOGD("Entered");
+ LoggerD("Entered");
getUniqueOpId();
const int non_err = EMAIL_ERROR_NONE;
m_slot_size = slot_size;
}
-// m_proxy_sync = std::make_shared<DBus::SyncProxy>(
-// DBus::Proxy::DBUS_PATH_NETWORK_STATUS,
-// DBus::Proxy::DBUS_IFACE_NETWORK_STATUS);
-// if (!m_proxy_sync) {
-// LOGE("Sync proxy is null");
-// throw Common::UnknownException("Sync proxy is null");
-// }
-// m_proxy_sync->signalSubscribe();
-//
+ m_proxy_sync = std::make_shared<DBus::SyncProxy>(
+ DBus::Proxy::DBUS_PATH_NETWORK_STATUS,
+ DBus::Proxy::DBUS_IFACE_NETWORK_STATUS);
+ if (!m_proxy_sync) {
+ LOGE("Sync proxy is null");
+ //TODO throw Common::UnknownException("Sync proxy is null");
+ }
+ m_proxy_sync->signalSubscribe();
+
// m_proxy_load_body = std::make_shared<DBus::LoadBodyProxy>(
// DBus::Proxy::DBUS_PATH_NETWORK_STATUS,
// DBus::Proxy::DBUS_IFACE_NETWORK_STATUS);
EmailManager::~EmailManager()
{
- LOGD("Entered");
+ LoggerD("Entered");
}
//void EmailManager::addDraftMessagePlatform(int account_id,
void EmailManager::sync(void* data)
{
- LOGD("Entered");
+ LoggerD("Entered");
SyncCallbackData* callback = static_cast<SyncCallbackData*>(data);
if(!callback){
LOGE("Callback is null");
#include "messaging_util.h"
#include "message_service.h"
-//#include "DBus/Connection.h"
-//#include "DBus/SyncProxy.h"
+#include "DBus/Connection.h"
+#include "DBus/SyncProxy.h"
//#include "DBus/LoadBodyProxy.h"
//#include "DBus/LoadAttachmentProxy.h"
//#include "DBus/MessageProxy.h"
int m_slot_size;
-// DBus::SyncProxyPtr m_proxy_sync;
+ DBus::SyncProxyPtr m_proxy_sync;
// DBus::LoadBodyProxyPtr m_proxy_load_body;
// DBus::LoadAttachmentProxyPtr m_proxy_load_attachment;
// DBus::MessageProxyPtr m_proxy_messageStorage;
'message_attachment.cc',
'message_attachment.h',
'message_body.cc',
- 'message_body.h'
+ 'message_body.h',
+ 'DBus/Connection.cpp',
+ 'DBus/Connection.h',
+ 'DBus/EmailSignalProxy.cpp',
+ 'DBus/EmailSignalProxy.h',
+ #'DBus/LoadAttachmentProxy.cpp',
+ #'DBus/LoadAttachmentProxy.h',
+ #'DBus/LoadBodyProxy.cpp',
+ #'DBus/LoadBodyProxy.h',
+ #'DBus/MessageProxy.cpp',
+ #'DBus/MessageProxy.h',
+ 'DBus/Proxy.cpp',
+ 'DBus/Proxy.h',
+ #'DBus/SendProxy.cpp',
+ #'DBus/SendProxy.h',
+ 'DBus/SyncProxy.cpp',
+ 'DBus/SyncProxy.h',
],
'includes': [
'../common/pkg-config.gypi',