Update change log and spec for wrt-plugins-tizen_0.4.52
[framework/web/wrt-plugins-tizen.git] / src / Messaging / MailSync.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include <utility>
19 #include <email-types.h>
20 #include <email-api.h>
21 #include <email-api-network.h>
22 #include <email-api-init.h>
23 #include <email-api-account.h>
24
25 #include <Commons/Exception.h>
26 #include <Commons/ThreadPool.h>
27 #include "ReqReceiverMessage.h"
28 #include "EventMessagingService.h"
29 #include "IAttachment.h"
30
31 #include "MailSync.h"
32 #include "SyncNetworkStatus.h"
33 #include "IMessage.h"
34 //for vconf
35 #include <vconf.h>
36 #include <vconf-keys.h>
37
38 #include <Logger.h>
39
40 namespace {
41 const char* DBUS_FILTER_NETWORK_STATUS =
42     "type='signal',interface='User.Email.NetworkStatus'";
43 //const char* DBUS_FILTER_EMAIL_RECEIVED =
44 //    "type='signal',interface='User.Email.StorageChange'";
45 }
46
47 namespace DeviceAPI {
48 namespace Messaging {
49
50 using namespace WrtDeviceApis::Commons;
51
52 MailSync& MailSync::getInstance()
53 {
54     static MailSync instance;
55     return instance;
56 }
57
58 MailSync::MailSync() :
59     m_dbusThread(new DPL::Thread()),
60     m_dbus(new DBus::Connection())
61 {
62     m_dbusThread->Run();
63
64     m_dbus->setWorkerThread(m_dbusThread.Get());
65     m_dbus->AddListener(this);
66     m_dbus->SwitchAllListenersToThread(
67         ThreadPool::getInstance().getThreadRef(ThreadEnum::MESSAGING_THREAD)
68         );
69     m_dbus->addFilter(DBUS_FILTER_NETWORK_STATUS);
70     m_dbus->open(DBUS_BUS_SYSTEM);
71
72     //start email service
73     int error = email_service_begin();
74         if (error == EMAIL_ERROR_NONE) {
75             LoggerD("Email service Begin\n");
76             if (EMAIL_ERROR_NONE == email_open_db()) {
77                     LoggerD("Email open DB success\n");
78             }
79             else{
80                     LoggerD("Email open DB failed\n");
81         }
82         }
83         else{
84             LoggerD("Email service not started\n");
85             LoggerD("Error : " << error);
86         }
87
88         //get retriving count
89         int slot_size = -1;
90         vconf_get_int("db/private/email-service/slot_size", &(slot_size));
91         if ( slot_size > 0 )
92                 m_default_slot_size = slot_size;
93
94         LoggerD( "Slot Size : " << m_default_slot_size );
95         
96 }
97
98 MailSync::~MailSync()
99 {
100     m_dbus->RemoveListener(this);
101     m_dbus->close();
102
103     m_dbusThread->Quit();
104
105     //close email service
106         if (EMAIL_ERROR_NONE == email_close_db()) {
107                 LoggerD("Email Close DB Success\n");
108                 if (EMAIL_ERROR_NONE == email_service_end())
109                 {
110                 LoggerD("Email service close Success\n");
111                 }
112                 else
113                 {
114                 LoggerD("Email service end failed\n");
115         }
116         }
117         else{
118                 LoggerD("Email Close DB failed\n");
119 }
120 }
121
122 int MailSync::downloadBody( const IEmailPtr& mail )
123 {       
124         if ( mail )
125         {       
126                 int mailId = mail->convertId(mail->getIdRef());         // get mail id
127                 LoggerD("start attachment, mail Id : " << mail->getIdRef());
128                 SyncRequestIterator it;
129                 int synType;
130                 for( it = m_SyncRequests.begin(); it != m_SyncRequests.end(); ++it)
131                 {
132                         synType = it->second.syncType;
133                         LoggerD("synType : " << synType);
134
135                         if( synType != MESSAGING_SERVICE_SYNC_TYPE_DOWNLOAD_BODY )
136                         {
137                                 LoggerD("skip");
138                                 continue;
139                         }
140                         const IEmailPtr& email = it->second.mail;
141                         LoggerD ( "Requests mail ID:" <<  mail->convertId(email->getIdRef()) );
142                         if ( mailId == mail->convertId(email->getIdRef()))
143                         {
144                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
145                                         "download Body: " << mailId << " already requested to be download Body.");
146                         }
147                 }               
148         }
149         
150         return downloadBodyInternal(mail, mail->getAccountID());
151         
152 }
153
154 void MailSync::cancelDownloadBody(int handle)
155 {
156         SyncRequestIterator it = m_SyncRequests.find(handle);
157         if ( m_SyncRequests.end() != it)
158         {
159                 if (  it->second.messagingService )
160                         cancelEmailJobInternal( it->second.messagingService->getAccountID() , it->second.handle);
161                 //cancelDownloadBodyInternal(it->second.mail, it->second.handle );
162         }
163         else
164         {
165                 LoggerD("Don't find cancel DownloadBody handle : " << handle);
166                 //ThrowMsg(WrtDeviceApis::Commons::NotFoundException, "Email: " << mailId << " not found.");
167         }
168         
169 }
170
171 void MailSync::cancelDownloadAttachment(int handle)
172 {
173
174         SyncRequestIterator it = m_SyncRequests.find(handle);
175         if ( m_SyncRequests.end() != it)
176         {
177                 if (  it->second.messagingService )
178                         cancelEmailJobInternal( it->second.messagingService->getAccountID() , it->second.handle);
179                 //cancelDownloadBodyInternal(it->second.mail, it->second.handle );
180         }
181         else
182         {
183                 LoggerD("Don't find cancel DownloadAttachment handle : " << handle);
184         }
185         
186 }
187
188 int MailSync::downloadAttachment(const IEmailPtr& mail, const IAttachmentPtr& attachment)
189 {       
190         if ( mail && attachment )
191         {       
192                 //int mailId = mail->convertId(mail->getIdRef());               // get mail id
193                 LoggerD("start attachment, mail Id : " << mail->getIdRef());
194                 SyncRequestIterator it;
195                 int synType;
196                 for( it = m_SyncRequests.begin(); it != m_SyncRequests.end(); ++it)
197                 {
198                         synType = it->second.syncType;
199                         LoggerD("synType : " << synType);
200
201                         if( synType != MESSAGING_SERVICE_SYNC_TYPE_DOWNLOAD_ATTACHMENT )
202                         {
203                                 LoggerD("skip");
204                                 continue;
205                         }
206
207                         const IAttachmentPtr& iattachment = it->second.attachment;
208                         LoggerD ( "Requests Attachment ID:" <<  iattachment->getAttachmentID() << " Input Attachment ID: "  << attachment->getAttachmentID());
209                         if (iattachment->getAttachmentID() == attachment->getAttachmentID())
210                         {
211                                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
212                                         "Attachment: " << attachment->getAttachmentID() << " already requested to be download Attachment.");
213                         }
214                 }
215         }
216
217         return downloadAttachmentInternal(mail, mail->getAccountID(), attachment);
218
219 }
220
221 int MailSync::syncAccount(const IMessagingServicePtr& messagingService, const int limit)
222 {
223         LoggerD("syncAccount : " << limit);
224         if (messagingService)
225         {
226                 int accountId = messagingService->getAccountID();
227                 LoggerD("start sync, account Id : " << accountId);
228                 SyncRequestIterator it;
229                 int synType;
230                 for( it = m_SyncRequests.begin(); it != m_SyncRequests.end(); ++it)
231                 {
232                         synType = it->second.syncType;
233                         LoggerD("synType : " << synType);
234                         
235                         if( synType != MESSAGING_SERVICE_SYNC_TYPE_SYNC )
236                         {
237                                 LoggerD("skip");
238                                 continue;
239                         }
240                 
241                         const IMessagingServicePtr& messagingService = it->second.messagingService;
242                         if (messagingService && messagingService->getAccountID() == accountId)
243                         {
244                                 LoggerD("accountId is sync requested already");
245 //                              ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Sync: " << accountId << " already requested to be Sync Account.");
246                         }
247                 }
248                 return syncAccountInternal(messagingService, limit);
249         }
250         else
251         {
252                 LoggerD("messagingService is NULL");
253         }
254
255         LoggerD("end sync" );
256         return -1;
257 }       
258
259 int MailSync::syncAccountInternal( const IMessagingServicePtr& messagingService, const int limit)
260 {
261         LoggerD("syncAccountInternal limit: " << limit);
262         
263         int account_id = messagingService->getAccountID();
264         int err = 0;
265 //      email_mailbox_t mailbox ;
266         int email_handle = 0;
267         
268 //      memset(&mailbox, 0, sizeof(email_mailbox_t));
269 //      mailbox.mailbox_name = NULL;                            /* all folders. */
270 //      mailbox.account_id = account_id; //set account id.
271         int slot_size;
272         
273         if ( limit < 0 )
274                 slot_size = m_default_slot_size;
275         else
276                 slot_size = limit;
277         
278         email_set_mail_slot_size(0, 0, slot_size);
279                         
280 //      LoggerD("mailbox.account_id " << mailbox.account_id );
281 //      err = email_sync_header(&mailbox, &email_handle);
282 //      LoggerD("emf_handle " << emf_handle);
283
284         err = email_sync_header(account_id, 0, &email_handle);
285         LoggerD("email_handle " << email_handle);
286
287         if (err != EMAIL_ERROR_NONE) {
288                 LoggerD("fail to sync all folders - err : " << err);
289         }
290         else
291         {
292                 LoggerD("Insert sync request");
293                 SyncRequestData data = SyncRequestData(email_handle, MESSAGING_SERVICE_SYNC_TYPE_SYNC, messagingService);
294                 m_SyncRequests.insert(std::make_pair(email_handle, data));
295         }
296
297         return email_handle;
298 }
299
300 void MailSync::syncAccountCancel(const int handle)
301 {
302         LoggerD("sync cancel");
303
304         SyncRequestIterator it = m_SyncRequests.find(handle);
305         if ( m_SyncRequests.end() != it)
306         {
307                 if (  it->second.messagingService )
308                         cancelEmailJobInternal( it->second.messagingService->getAccountID() , it->second.handle);
309         }
310         else
311         {
312                 LoggerD("Don't find cancel Sync handle : " << handle);
313                 //ThrowMsg(WrtDeviceApis::Commons::NotFoundException, "Email: " << mailId << " not found.");
314         }       
315 }
316
317 int MailSync::syncFolder(const IMessagingServicePtr& messagingService, const int folder_id, const int limit)
318 {
319         LoggerD("sync folder : " << folder_id << " limit : " << limit);
320         
321         if (messagingService)
322         {
323                 int accountId = messagingService->getAccountID();
324                 LoggerD("start sync, account Id : " << accountId);
325                 SyncRequestIterator it;
326                 int synType;
327                 for( it = m_SyncRequests.begin(); it != m_SyncRequests.end(); ++it)
328                 {
329                         synType = it->second.syncType;
330                         LoggerD("synType : " << synType);
331                         
332                         if( synType != MESSAGING_SERVICE_SYNC_TYPE_SYNC_FOLDER )
333                         {
334                                 LoggerD("skip");
335                                 continue;
336                         }
337                 
338                         const IMessagingServicePtr& messagingService = it->second.messagingService;
339                         if (messagingService && messagingService->getAccountID() == accountId 
340                                 && it->second.folderId == folder_id)
341                         {
342                                 LoggerD("accountId is syncFolder requested already");
343 //                              ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Sync: " << accountId << " already requested to be Sync Account.");
344                         }
345                 }
346                 
347                 return syncFolderInternal(messagingService, folder_id, limit);
348         }
349         else
350         {
351                 LoggerD("messagingService is NULL");
352         }
353
354         return -1;
355                 
356 }
357
358 void MailSync::syncFolderCancel(const int handle)
359 {
360         LoggerD("sync Folder Cancel");
361
362         SyncRequestIterator it = m_SyncRequests.find(handle);
363         if ( m_SyncRequests.end() != it)
364         {
365                 if (  it->second.messagingService )
366                         cancelEmailJobInternal( it->second.messagingService->getAccountID() , it->second.handle);
367         }
368         else
369         {
370                 LoggerD("Don't find cancel Sync Folder handle : " << handle);
371                 //ThrowMsg(WrtDeviceApis::Commons::NotFoundException, "Email: " << mailId << " not found.");
372         }
373 }
374
375 int MailSync::syncFolderInternal(const IMessagingServicePtr& messagingService, const int folder_id, const int limit)
376 {
377         LoggerD("Folder Id=" << folder_id << " limit : " << limit);
378
379         int account_id = messagingService->getAccountID();
380
381         int email_handle = 0;
382         int err = 0;
383         int slot_size = 0;
384         email_mailbox_t* mailbox = NULL;
385         
386 //      char* mailbox_name = strdup(folderName.c_str());
387         
388         err = email_get_mailbox_by_mailbox_id(folder_id, &mailbox);
389         if (EMAIL_ERROR_NONE != err) {
390                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
391                         "Couldn't set mail solt size. [" << err << "]");
392         }       
393
394         if (mailbox == NULL) {
395                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,     "Couldn't get mailbox");
396         }
397         
398 //      char* mailbox_name = strdup(mailbox->mailbox_name);
399         
400         if ( limit < 0 )
401                 slot_size = m_default_slot_size;
402         else
403                 slot_size = limit;
404         
405         err = email_set_mail_slot_size(0, mailbox->mailbox_id, slot_size);
406         if (EMAIL_ERROR_NONE != err) {
407                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
408                         "Couldn't set mail solt size. [" << err << "]");
409         }
410         
411 //      err = email_sync_header(mailbox, &email_handle);
412         err = email_sync_header(account_id, mailbox->mailbox_id, &email_handle);
413         if (err != EMAIL_ERROR_NONE) {
414                 LoggerD("fail to sync folders - err : " << err);
415         }
416         else
417         {
418                 LoggerD("Insert sync request");
419
420                 SyncRequestData data = SyncRequestData(email_handle,    MESSAGING_SERVICE_SYNC_TYPE_SYNC_FOLDER, messagingService, folder_id);
421                 m_SyncRequests.insert(std::make_pair(email_handle, data));
422         }
423
424 //      if (mailbox_name)
425 //              free(mailbox_name);
426
427         if ( mailbox != NULL )
428         {
429                 if  (  EMAIL_ERROR_NONE != email_free_mailbox( &mailbox , 1) )
430                         LoggerD("fail to email_free_mailbox - err ");
431                 mailbox = NULL;
432         }
433         
434         return email_handle;
435 }
436         
437
438 // TODO Copied from former solution, refactor it.
439 void MailSync::OnEventReceived(const DBus::MessageEvent& event)
440 {
441         LoggerD("OnEventReceived");
442         SyncNetworkStatusPtr syncNetworkStatus(new SyncNetworkStatus(event.GetArg0()));
443         int mailId = syncNetworkStatus->getMailId();    //if email body download mode.
444         int status = syncNetworkStatus->getStatus();
445         int handle = syncNetworkStatus->getHandle();
446
447         LoggerD("mailId : " << mailId << " status : " << status << " handle : " << handle);
448         // if Attachment Load
449         if ( status == NOTI_DOWNLOAD_ATTACH_FINISH ||status == NOTI_DOWNLOAD_ATTACH_FAIL )
450         {
451                 int nth = handle;
452                 LoggerD(" Debus mailID = " <<  mailId <<  " , Nth = " << nth );
453
454                 SyncRequestIterator it = m_SyncRequests.begin();
455                 for ( ; it != m_SyncRequests.end(); it++ )
456                 {
457                         const IEmailPtr& mail = it->second.mail;
458
459                         LoggerD(" request mailID = " <<  mail->getUID() <<  " , Nth = " << (it->second.attachment)->getNth() );
460                         if ( mail->getUID() == mailId && nth == (it->second.attachment)->getNth())
461                         {
462                                 EventMessagingServiceReqReceiver* requestReceiver = mail->getRequestReceiver();
463                                 if ( mail && requestReceiver )
464                                 {
465                                         EventMessagingServicePtr event = mail->getMessagingServiceEvent();
466 //                                      EventMessagingServicePtr event = messagingService->getEventFromHandle(handle);
467
468                                         if (status == NOTI_DOWNLOAD_ATTACH_FINISH)
469                                         {
470                                                 LoggerD(" Attachment Finish " );
471                                                 const IAttachmentPtr& attachment = it->second.attachment;
472                                                 if (attachment)
473                                                 {
474
475                                                         email_attachment_data_t* attachment_data = NULL;
476                                                         int attachmentId = attachment->getAttachmentID();
477                                                         LoggerD("Attachment ID = " << attachmentId);
478
479                                                         int err = email_get_attachment_data(attachmentId, &attachment_data);
480                                                         if (err == EMAIL_ERROR_NONE) {
481                                                                 LoggerD("attachment Name : " << attachment_data->attachment_name);
482                                                                 LoggerD("attachment ID : " << attachment_data->attachment_id);
483
484                                                                 attachment->init(attachment_data->attachment_path, false);
485                                                                 if(attachment_data->attachment_mime_type)
486                                                                 {
487                                                                         LoggerD("attachment attachment_mime_type : " << attachment_data->attachment_mime_type);
488                                                                         attachment->setMimeType(attachment_data->attachment_mime_type);
489                                                                 }
490                                                                 LoggerD("attachment getMimeTypes : " << attachment->getMimeType());
491                                                         }
492                                                         else
493                                                         {
494                                                                 LoggerD("fail to email_get_attachment_data - err : " << err);
495                                                         }
496
497                                                         if ( attachment_data != NULL )
498                                                         {
499                                                                 email_free_attachment_data(&attachment_data, 1);
500                                                         }
501
502                                                 }
503
504                                         }
505                                         else
506                                         {
507                                                 event->setExceptionCode( WrtDeviceApis::Commons::ExceptionCodes::UnknownException);
508                                                 LoggerD(" Attachment Failed " );
509                                         }
510
511                                         LoggerD("remove downloadAttachment request");
512                                         LoggerD("handle : " << it->first );
513                                         requestReceiver->ManualAnswer(event);
514                                         m_SyncRequests.erase(it->first);
515
516                                 }
517                                 break;
518                         }
519                 } 
520         }
521         else if ( status == NOTI_DOWNLOAD_ATTACH_START )
522         {
523                 LoggerD("DownLoading... attachment : size = " << syncNetworkStatus->getErrorCode());
524                 return;
525         }
526
527         SyncRequestIterator it = m_SyncRequests.find(handle);
528         if ( m_SyncRequests.end() != it)
529         {
530                 int syncType = it->second.syncType;
531                 LoggerD(" Sync ... handle : " << handle << " status : " << status << " SyncType: " << syncType);
532
533                 switch(syncType)
534                 {
535                         case MESSAGING_SERVICE_SYNC_TYPE_SYNC:
536                         {
537                                 LoggerD(" Sync Account");
538                                 const IMessagingServicePtr& messagingService = it->second.messagingService;
539                                 EventMessagingServiceReqReceiver* requestReceiver = messagingService->getRequestReceiver();
540
541                                 if ( messagingService && requestReceiver)
542                                 {
543                                         EventMessagingServicePtr event = messagingService->getEventFromHandle(handle);
544                                         // get event using handle from m_opRequests;
545                                         if (event)
546                                         {
547                                                 if ( status == NOTI_DOWNLOAD_FINISH )
548                                                 {
549                                                         LoggerD("Sync Success");
550                                                         requestReceiver->ManualAnswer(event);
551                                                         m_SyncRequests.erase( handle );
552                                                 }
553                                                 else if ( status == NOTI_DOWNLOAD_FAIL )
554                                                 {
555                                                         LoggerD("Sync Fail");
556                                                         event->setExceptionCode( WrtDeviceApis::Commons::ExceptionCodes::UnknownException );
557                                                         requestReceiver->ManualAnswer(event);
558                                                         m_SyncRequests.erase( handle );
559                                                 }
560                                         }
561                                 }
562                                 else
563                                 {
564                                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "request Receiver is NULL. ");
565                                 }
566                                 break;
567                         }
568                         case MESSAGING_SERVICE_SYNC_TYPE_SYNC_FOLDER:
569                         {
570                                 LoggerD("Sync Folder");
571                                 const IMessagingServicePtr& messagingService = it->second.messagingService;
572                                 EventMessagingServiceReqReceiver* requestReceiver = messagingService->getRequestReceiver();
573
574                                 if ( messagingService && requestReceiver)
575                                 {
576                                         EventMessagingServicePtr event = messagingService->getEventFromHandle(handle);
577                                         if (event)
578                                         {
579                                                 if ( status == NOTI_DOWNLOAD_FINISH )
580                                                 {
581                                                         LoggerD("Sync Success");
582                                         requestReceiver->ManualAnswer(event);
583                                                         m_SyncRequests.erase( handle );
584                                                 }
585                                                 else if ( status == NOTI_DOWNLOAD_FAIL )
586                                                 {
587                                                         LoggerD("Sync Fail");
588                                         event->setExceptionCode( WrtDeviceApis::Commons::ExceptionCodes::UnknownException );
589                                                         requestReceiver->ManualAnswer(event);
590                                                         m_SyncRequests.erase( handle );
591                                                 }
592                                         }
593                                 }
594                                 else
595                                 {
596                                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "request Receiver is NULL. ");
597                                 }
598                                 break;
599                         }
600                         case MESSAGING_SERVICE_SYNC_TYPE_DOWNLOAD_BODY:
601                         {
602                                 LoggerD(" DownLoad Body");
603                                 const IEmailPtr& mail = it->second.mail;        // IEmailPtr
604                                 EventMessagingServiceReqReceiver* requestReceiver = mail->getRequestReceiver();
605                                 if (mail && requestReceiver) {
606                                         EventMessagingServicePtr event = mail->getMessagingServiceEvent();
607                         
608                                         if ( status == NOTI_DOWNLOAD_BODY_FINISH )
609                                         {
610                                                 event->m_message->readAllData();
611
612                                                 std::vector<IAttachmentPtr> attachments = mail->getAttachments();
613                                                 std::vector<IAttachmentPtr> inlineAttachments = mail->getInlineAttachments();
614
615                                                 for (unsigned int idx = 0; idx < attachments.size() ; idx++ )
616                                                 {
617                                                         LoggerD("set Attachment ID = " << attachments[idx]->getAttachmentID());
618                                                         attachments[idx]->setMessage(event->m_message);
619
620                                                 }
621                                                 for (unsigned int idx = 0; idx < inlineAttachments.size() ; idx++ )
622                                                 {
623                                                         LoggerD("set inline Attachment ID = " << inlineAttachments[idx]->getAttachmentID());
624                                                         inlineAttachments[idx]->setMessage(event->m_message);
625                                                 }
626
627                                                 requestReceiver->ManualAnswer(event);
628                                                 m_SyncRequests.erase( handle );
629                                         }
630                                         else if ( status == NOTI_DOWNLOAD_BODY_FAIL )
631                                         {
632                                                 event->setExceptionCode( WrtDeviceApis::Commons::ExceptionCodes::UnknownException);
633                                                 requestReceiver->ManualAnswer(event);
634                                                 m_SyncRequests.erase( handle );
635                                         }
636                                 }
637                                 else
638                                 {
639                                         ThrowMsg(WrtDeviceApis::Commons::PlatformException, "request Receiver is NULL. ");
640                                 }
641                                 break;
642                         }
643                 }
644         }
645 }
646
647 int MailSync::downloadBodyInternal( const IEmailPtr& mail, int account_id)
648 {
649         
650         LoggerD("downloadInternal");
651
652         int err = 0;
653         int mailId = mail->convertId(mail->getIdRef());
654         int email_handle = 0;
655         
656         LoggerD("folder type = " << mail->getCurrentFolder());
657         LoggerD("mail ID :" << mailId );
658
659         err = email_download_body(mailId, 0, &email_handle);
660         if (err != EMAIL_ERROR_NONE) {
661                 LoggerD("fail to downloadBody - err : " << err);
662                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Failed to initialize downloadBody request. [" << err << "]");
663         }
664         else
665         {
666                 LoggerD("Insert downloadBody request");
667                 LoggerD("handle : " << email_handle);
668                 SyncRequestData data = SyncRequestData(email_handle,    MESSAGING_SERVICE_SYNC_TYPE_DOWNLOAD_BODY, mail);
669                 m_SyncRequests.insert(std::make_pair(email_handle, data));
670         }
671
672         return email_handle;
673
674 }
675
676 int MailSync::downloadAttachmentInternal(const IEmailPtr& mail, int account_id, const IAttachmentPtr& attachment)
677 {
678         LoggerD("downloadAttachmentInternal");
679         if (!mail) {
680                 LoggerE("mail is NULL");
681                 Throw(WrtDeviceApis::Commons::PlatformException);
682         }
683         
684         int err = 0;
685         int nth = 0;
686         int mailId = mail->convertId(mail->getIdRef());
687         int email_handle = 0;
688         
689         email_mail_data_t* result = NULL;
690
691         int error;
692         error = email_get_mail_data(mailId, &result);
693         if (EMAIL_ERROR_NONE != error) {
694                         ThrowMsg(WrtDeviceApis::Commons::PlatformException,
695                                  "Couldn't find message " << mailId << ". [" << error << "]");
696         }
697
698         LoggerD("Attachment ID :" << attachment->getAttachmentID());    
699
700         //get nth 
701         std::vector<IAttachmentPtr> attachments = mail->getAttachments();
702         std::vector<IAttachmentPtr> inlineAttachments = mail->getInlineAttachments();
703         unsigned int attachmentSize = attachments.size();
704         unsigned int inlineAttachmentSize = inlineAttachments.size();
705
706         LoggerD( "attachment sizes = " << attachmentSize << ",inline attachment size : " << inlineAttachmentSize);      
707         for ( unsigned int i = 0 ; i < attachmentSize ; i ++)
708         {
709                 LoggerD( "attachment ID is = " << attachments[i]->getAttachmentID());
710                 if (attachments[i]->getAttachmentID() == attachment->getAttachmentID())
711                 {
712 //                      nth = i;
713                         nth = attachments[i]->getNth();
714                         break;
715                 }
716         }
717         for ( unsigned int i = 0 ; i < inlineAttachmentSize ; i ++)
718         {
719                 LoggerD( "inline attachment ID is = " << inlineAttachments[i]->getAttachmentID());
720                 if (inlineAttachments[i]->getAttachmentID() == attachment->getAttachmentID())
721                 {
722 //                      nth = i;
723                         nth = inlineAttachments[i]->getNth();
724                         break;
725                 }
726         }
727         
728         LoggerD("nth = " << nth);       
729         LoggerD("attachment Order Index = " << nth);
730         err = email_download_attachment(mailId, nth , &email_handle);
731         if (err != EMAIL_ERROR_NONE) {
732                 LoggerD("fail to downloadAttachment - err : " << err);
733                 ThrowMsg(WrtDeviceApis::Commons::PlatformException, "Failed to initialize downloadAttachment request. [" << err << "]");
734         }
735         else
736         {
737                 LoggerD("Insert downloadAttachment request");
738                 LoggerD("handle : " << email_handle);
739                 SyncRequestData data = SyncRequestData( email_handle,
740                         MESSAGING_SERVICE_SYNC_TYPE_DOWNLOAD_ATTACHMENT, mail, attachment );
741                 m_SyncRequests.insert(std::make_pair(email_handle, data));
742         }
743
744         if ( result )
745                 if  (  EMAIL_ERROR_NONE != email_free_mail_data( &result , 1) )
746                         LoggerD("fail to email_free_mail_data - err ");
747         
748         return email_handle;
749 }
750
751 void MailSync::cancelEmailJobInternal(int accountId, int handle)
752 {
753         LoggerD("cancel Email Job, account : " <<accountId << " handle : " << handle);
754
755         int error = email_cancel_job(accountId, handle,EMAIL_CANCELED_BY_USER);
756         if (EMAIL_ERROR_NONE != error) {
757                 LoggerD("error code : " << error );
758                 ThrowMsg(WrtDeviceApis::Commons::PlatformException,
759                  "Couldn't cancel email job handle: " << handle);
760         }
761
762         m_SyncRequests.erase(handle);
763 }
764
765
766 }
767 }