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