Update change log and spec for wrt-plugins-tizen_0.2.73
[profile/ivi/wrt-plugins-tizen.git] / src / platform / Tizen / Messaging / MailSender.cpp
1 /*
2 * Copyright (c) 2011 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 /**
18  * @author          Zbigniew Kostrzewa (z.kostrzewa@samsung.com)
19  */
20 #include <utility>
21 #include <email-types.h>
22 #include <email-api.h>
23 #include <email-api-network.h>
24 #include <email-api-init.h>
25 #include <email-api-account.h>
26
27 #include <dpl/log/log.h>
28 #include <dpl/assert.h>
29 #include <Commons/Exception.h>
30 #include <Commons/ThreadPool.h>
31 #include <API/Messaging/ReqReceiverMessage.h>
32 #include <API/Messaging/EventSendMessage.h>
33 #include <API/Messaging/EventMessagingService.h>
34 #include <API/Messaging/EventOnSendingFailed.h>
35 #include "MailSender.h"
36 #include "NetworkStatus.h"
37 #include "Messaging.h"
38
39 namespace {
40 const char* DBUS_FILTER_NETWORK_STATUS =
41     "type='signal',interface='User.Email.NetworkStatus'";
42 }
43
44 namespace TizenApis {
45 namespace Platform {
46 namespace Messaging {
47
48 using namespace WrtDeviceApis::Commons;
49 using namespace WrtDeviceApis::CommonsJavaScript;
50
51 MailSender& MailSender::getInstance()
52 {
53     static MailSender instance;
54     return instance;
55 }
56
57 int MailSender::send(const Api::Messaging::IEmailPtr& mail)
58 {
59     Assert(mail && "Mail must not be NULL.");
60
61     int mailId = mail->convertId(mail->getIdRef());
62     LogDebug("send mailId = " << mailId);
63     SendRequestsIterator it = m_requests.find(mailId);
64     if (m_requests.end() != it) {
65         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
66                  "Email: " << mailId << " already requested to be send.");
67     }
68
69     return sendInternal(mail);
70 }
71
72 void MailSender::cancel(int handle)
73 {
74     SendRequestsIterator it = m_requests.find(handle);
75     if (m_requests.end() == it) {
76         //ThrowMsg(WrtDeviceApis::Commons::PlatformException,
77         //         "Email handle : " << handle << " not found.");
78         LogDebug("Email handle" << handle  << " not found!");
79           return;
80     }
81     else
82     {
83           cancelInternal(it->second);
84     }
85 }
86
87 // TODO Copied from former solution, refactor it.
88 void MailSender::OnEventReceived(const DBus::MessageEvent& event)
89 {
90     LogDebug("HERE");
91     NetworkStatusPtr msg(new NetworkStatus(event.GetArg0()));
92     int mailId = msg->getMailId();
93     LogDebug("status : " << msg->getStatus() << " mailId : " << mailId);
94     int handle = 0;
95
96     if ( msg->getStatus() == NOTI_SEND_FINISH || msg->getStatus() == NOTI_SEND_FAIL)
97     {
98                 //find handle
99                 SendRequestsIterator it = m_requests.begin();
100                 for (; it != m_requests.end() ; it++)
101                 {
102                         if ( it->second.mail->getUID() == mailId)
103                         {
104                                 handle = it->first;
105                                 LogDebug("handle : " << handle);
106                                 break;
107                         }
108                 }
109
110                 if (msg->getStatus() == NOTI_SEND_FAIL)
111                 {
112                         LogDebug(" Error Code : " << msg->getErrorCode());
113                 }
114     }
115     else 
116     {
117                 if ( msg->getStatus() == NOTI_SEND_START )
118                 {
119                         LogDebug("NOTI_SEND_START");
120                 }
121                 else if ( msg->getStatus() == NOTI_SEND_CANCEL )
122                 {
123                         LogDebug("NOTI_SEND_CANCEL");
124                 }
125
126                 return ;
127     }
128         
129     LogDebug("handle : " << handle);
130         
131     SendRequestsIterator it = m_requests.find(handle);  //find reqeuset
132     if (m_requests.end() != it) {
133         switch (msg->getStatus()) {
134         case NOTI_SEND_START:
135             LogInfo("Start sending e-mail: " << mailId);
136             break;
137
138         case NOTI_SEND_FINISH:
139         {
140             const Api::Messaging::IEmailPtr& mail = it->second.mail;
141             //Api::Messaging::EventSendMessageReqReceiver* requestReceiver = mail->getRequestReceiver();
142             Api::Messaging::EventMessagingServiceReqReceiver* requestReceiver = mail->getRequestReceiver();
143                 
144             if (requestReceiver) {
145                 //Api::Messaging::EventSendMessagePtr event = mail->getSendMessageEvent();
146                 Api::Messaging::EventMessagingServicePtr event = mail->getMessagingServiceEvent();
147                      if (event)
148                         {
149                                 for (size_t i = 0; i < mail->getToRecipients().getRecipientSize(); ++i) {
150                                         event->m_successRecipients.push_back(mail->getToRecipients().getRecipient(i));
151                                 }
152                                 for (size_t i = 0; i < mail->getCcRecipients().getRecipientSize(); ++i) {
153                                         event->m_successRecipients.push_back(mail->getCcRecipients().getRecipient(i));
154                                 }
155                                 for (size_t i = 0; i < mail->getBccRecipients().getRecipientSize(); ++i) {
156                                         event->m_successRecipients.push_back(mail->getBccRecipients().getRecipient(i));
157                                 }
158                                 
159                                 requestReceiver->ManualAnswer(event);
160                         }                
161                 
162             }
163                  mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_SENT);
164             LogInfo("E-mail sent: " << mailId);
165             m_requests.erase(mailId);
166             break;
167         }
168
169         case NOTI_SEND_FAIL:
170         {
171             const Api::Messaging::IEmailPtr& mail = it->second.mail;
172             Api::Messaging::EventOnSendingFailedEmitterPtr emitter = mail->getEmitter();
173             //Api::Messaging::EventSendMessageReqReceiver *requestReceiver = mail->getRequestReceiver();
174             Api::Messaging::EventMessagingServiceReqReceiver* requestReceiver = mail->getRequestReceiver();
175             if (emitter) {
176                 Api::Messaging::EventOnSendingFailedPtr event(
177                     new Api::Messaging::EventOnSendingFailed()
178                     );
179                 switch (msg->getErrorCode()) {
180                 case EMAIL_ERROR_NO_SIM_INSERTED:
181                 case EMAIL_ERROR_FLIGHT_MODE:
182                     event->setError(
183                         Api::Messaging::EventOnSendingFailed::NO_NETWORKING
184                         );
185                     break;
186
187                 case EMAIL_ERROR_SMTP_SEND_FAILURE:
188                 case EMAIL_ERROR_NO_SUCH_HOST:
189                 case EMAIL_ERROR_CONNECTION_FAILURE:
190                 case EMAIL_ERROR_CONNECTION_BROKEN:
191                 case EMAIL_ERROR_INVALID_SERVER:
192                 case EMAIL_ERROR_NO_RESPONSE:
193                     event->setError(
194                         Api::Messaging::EventOnSendingFailed::NO_CONNECTION
195                         );
196                     break;
197
198                 default:
199                     event->setError(Api::Messaging::EventOnSendingFailed::UNKNOWN);
200                 }
201                 emitter->emit(event);
202             } else if (requestReceiver) {
203                 //Api::Messaging::EventSendMessagePtr event = mail->getSendMessageEvent();
204                         Api::Messaging::EventMessagingServicePtr event = mail->getMessagingServiceEvent();
205                 event->setExceptionCode(
206                     WrtDeviceApis::Commons::ExceptionCodes::UnknownException
207                     );
208                 requestReceiver->ManualAnswer(event);
209             }
210                  mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_FAILED);
211                  
212             LogInfo("Sending e-mail: " << mailId <<
213                     " failed with error: " << msg->getErrorCode());
214             m_requests.erase(mailId);
215             break;
216         }
217         }
218     }
219 }
220
221 MailSender::MailSender() :
222     m_dbusThread(new DPL::Thread()),
223     m_dbus(new DBus::Connection())
224 {
225     m_dbusThread->Run();
226
227     m_dbus->setWorkerThread(m_dbusThread.Get());
228     m_dbus->AddListener(this);
229     m_dbus->SwitchAllListenersToThread(
230         ThreadPool::getInstance().getThreadRef(ThreadEnum::MESSAGING_THREAD)
231         );
232     m_dbus->addFilter(DBUS_FILTER_NETWORK_STATUS);
233     m_dbus->open(DBUS_BUS_SYSTEM);
234
235     //start email service
236         if (EMAIL_ERROR_NONE == email_service_begin()) {
237             LogDebug("Email service Begin\n");
238             if (EMAIL_ERROR_NONE == email_open_db()) {
239                     LogDebug("Email open DB success\n");
240             }
241             else{
242                     LogDebug("Email open DB failed\n");
243         }
244         }
245         else{
246             LogDebug("Email service not started\n");
247         }
248
249 }
250
251 MailSender::~MailSender()
252 {
253     m_dbus->RemoveListener(this);
254     m_dbus->close();
255
256     m_dbusThread->Quit();
257
258
259     //close email service
260         if (EMAIL_ERROR_NONE == email_close_db()) {
261                 LogDebug("Email Close DB Success\n");
262                 if (EMAIL_ERROR_NONE == email_service_end()){
263                 LogDebug("Email service close Success\n");
264                 }
265                 else{
266                 LogDebug("Email service end failed\n");
267         }
268         }
269         else{
270                 LogDebug("Email Close DB failed\n");
271         }
272         
273 }
274
275 int MailSender::sendInternal(const Api::Messaging::IEmailPtr& mail)
276 {
277     int mailId = mail->convertId(mail->getIdRef());
278
279     email_option_t options = {};
280     options.keep_local_copy = 1;
281     unsigned int email_handle=0;
282
283     int error = email_send_mail(mailId,
284                                 &options,
285                                 &email_handle);
286         
287     if (EMAIL_ERROR_NONE != error) {
288                 LogDebug("Send Fail error = " << error );
289                 m_requests.erase(mailId);
290                 mail->setMessageStatus(Api::Messaging::MESSAGE_STATUS_SENDING); 
291                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
292                          "Failed to initialize send request. [" << error << "]");
293           return -1;
294     }
295     else
296     {
297                 m_requests.insert(std::make_pair(email_handle, SendRequestData(email_handle, mail)));
298     }
299
300     LogDebug("emf Handle : " << email_handle 
301 << "requests size :" << m_requests.size() );
302   
303     return email_handle;        
304 }
305
306 void MailSender::cancelInternal(const SendRequestData& data)
307 {
308     int error = email_cancel_job(data.mail->getAccountID(), data.handle,EMAIL_CANCELED_BY_USER);
309     if (EMAIL_ERROR_NONE != error) {
310         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
311                  "Couldn't cancel sending for email: " <<
312                  data.mail->getIdRef());
313     }
314
315     m_requests.erase(data.handle);
316 }
317 }
318 }
319 }