Fix : The original content is restored again if CreateContent API fail
[platform/framework/native/content.git] / src / FCnt_DownloadManagerImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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  * @file        FCnt_DownloadManagerImpl.cpp
19  * @brief       This is the implementation file for the _DownloadManagerImpl class.
20  *
21  */
22
23 #include <errno.h>
24 #include <unistd.h>
25 #include <cstdlib>
26 #include <pthread.h>
27 #include <unique_ptr.h>
28
29 #include <download.h>
30
31 #include <FBaseSysLog.h>
32 #include <FBase_StringConverter.h>
33 #include <FBaseInteger.h>
34 #include <FBaseRtIEventArg.h>
35 #include <FBaseColIMap.h>
36 #include <FApp_AppInfo.h>
37
38 #include <FCntDownloadRequest.h>
39 #include <FCntIDownloadListener.h>
40
41 #include <FCnt_DownloadRequestImpl.h>
42 #include "FCnt_DownloadManagerImpl.h"
43
44 using namespace std;
45
46 using namespace Tizen::Base;
47 using namespace Tizen::Base::Runtime;
48 using namespace Tizen::Base::Collection;
49
50 namespace Tizen { namespace Content
51 {
52
53 static const int STATE_NONE = 0;
54 static const int STATE_QUEUED = 1;
55 static const int STATE_DOWNLOADING = 2;
56 static const int STATE_PAUSED = 3;
57 static const int STATE_CANCELLED = 4;
58 static const int STATE_COMPLETED = 5;
59 static const int STATE_FAILED = 6;
60
61
62 static const int SLP_STATE_NONE = 0;
63 static const int SLP_STATE_READY = 1;
64 static const int SLP_STATE_QUEUED = 2;
65 static const int SLP_STATE_DOWNLOADING = 3;
66 static const int SLP_STATE_PAUSED = 4;
67 static const int SLP_STATE_COMPLETED = 5;
68 static const int SLP_STATE_FAILED = 6;
69 static const int SLP_STATE_CANCELLED = 7;
70
71 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
72
73 _DownloadManagerImpl* _DownloadManagerImpl::__pInstance = null;
74
75 class _DownloadEventArg
76         : public IEventArg
77 {
78 public:
79         _DownloadEventArg()
80                 : __id(-1)
81                 , __state(STATE_NONE)
82                 , __result(-1)
83                 , __received(-1)
84                 , __total(-1)
85         {
86         }
87         RequestId __id;
88         int __state;
89         String __path;
90         result __result;
91         String __errorCode;
92         unsigned long long __received;
93         unsigned long long __total;
94 };
95
96 class _DownloadEvent
97         : public Event
98 {
99 protected:
100         virtual void FireImpl(IEventListener& listener, const IEventArg& arg)
101         {
102                 IDownloadListener* pListener = dynamic_cast<IDownloadListener*> (&listener);
103                 if (pListener != null)
104                 {
105                         const _DownloadEventArg* pArg = dynamic_cast<const _DownloadEventArg*>(&arg);
106                         if (pArg != null)
107                         {
108                                 switch(pArg->__state)
109                                 {
110                                         case STATE_NONE:
111                                         case STATE_QUEUED:
112                                                 break;
113
114                                         case STATE_DOWNLOADING:
115                                                 pListener->OnDownloadInProgress(pArg->__id, pArg->__received, pArg->__total);
116                                                 break;
117
118                                         case STATE_PAUSED:
119                                                 pListener->OnDownloadPaused(pArg->__id);
120                                                 break;
121
122                                         case STATE_COMPLETED:
123                                                 pListener->OnDownloadCompleted(pArg->__id, pArg->__path);
124                                                 break;
125
126                                         case STATE_FAILED:
127                                                 pListener->OnDownloadFailed(pArg->__id, pArg->__result, pArg->__errorCode);
128                                                 break;
129
130                                         case STATE_CANCELLED:
131                                                 pListener->OnDownloadCanceled(pArg->__id);
132                                                 break;
133
134                                         default:
135
136                                                 break;
137                                 }
138                         }
139                 }
140         }
141 };
142
143 static void
144 OnStateChanged(int download_id, download_state_e state, void* data)
145 {
146         SysLog(NID_CNT, "OnStateChanged, id = %d, state = %d", download_id, state);
147
148         RequestId reqId = (long)download_id;
149
150         _DownloadManagerImpl* pDMImpl = (_DownloadManagerImpl*)data;
151
152         if (!data)
153         {
154                 return;
155         }
156
157         switch(state)
158         {
159                 case SLP_STATE_NONE:
160                 case SLP_STATE_QUEUED:
161                 case SLP_STATE_DOWNLOADING:
162                         break;
163
164                 case SLP_STATE_PAUSED:
165                 {
166                         pthread_mutex_lock(&mutex);
167                         if (pDMImpl->__pEvent)
168                         {
169                                 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
170                                 pEventArg->__id = reqId;
171                                 pEventArg->__state = STATE_PAUSED;
172
173                                 pDMImpl->__pEvent->Fire(*pEventArg);
174                         }
175                         pthread_mutex_unlock(&mutex);
176
177                         break;
178                 }
179
180                 case SLP_STATE_COMPLETED:
181                 {
182                         pthread_mutex_lock(&mutex);
183                         if (pDMImpl->__pEvent)
184                         {
185                                 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
186                                 pEventArg->__id = reqId;
187                                 pEventArg->__state = STATE_COMPLETED;
188
189                                 char* path = null;
190                                 download_get_downloaded_file_path(download_id, &path);
191                                 pEventArg->__path = path;
192
193                                 delete[] path;
194
195                                 pDMImpl->__pEvent->Fire(*pEventArg);
196                         }
197                         pthread_mutex_unlock(&mutex);
198
199                         // Remove the resource from url_download
200                         pDMImpl->DestroyResources(reqId);
201
202                         break;
203                 }
204
205                 case SLP_STATE_FAILED:
206                 {
207                         pthread_mutex_lock(&mutex);
208                         if (pDMImpl->__pEvent)
209                         {
210                                 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
211                                 pEventArg->__id = reqId;
212                                 pEventArg->__state = STATE_FAILED;
213
214                                 download_error_e error;
215                                 download_get_error(download_id, &error);
216                                 pEventArg->__result = pDMImpl->ConvertToResult(error);
217
218                                 int http_status = 0;
219                                 download_get_http_status(download_id, &http_status);
220                                 pEventArg->__errorCode = Integer::ToString(http_status);
221
222                                 pDMImpl->__pEvent->Fire(*pEventArg);
223                         }
224                         pthread_mutex_unlock(&mutex);
225
226                         // Comment out due to resume the failed request
227                         //pDMImpl->DestroyResources(reqId);
228
229                         break;
230                 }
231
232                 case SLP_STATE_CANCELLED:
233                 {
234                         pthread_mutex_lock(&mutex);
235                         if (pDMImpl->__pEvent)
236                         {
237                                 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
238                                 pEventArg->__id = reqId;
239                                 pEventArg->__state = STATE_CANCELLED;
240
241                                 pDMImpl->__pEvent->Fire(*pEventArg);
242                         }
243                         pthread_mutex_unlock(&mutex);
244
245                         // Remove the resource from url_download
246                         pDMImpl->DestroyResources(reqId);
247
248                         break;
249                 }
250
251                 default:
252                         break;
253         }
254
255 }
256
257 static void
258 OnProgress(int download_id, unsigned long long received, void* data)
259 {
260         RequestId reqId = (long)download_id;
261
262         _DownloadManagerImpl* pDMImpl = (_DownloadManagerImpl*)data;
263
264         pthread_mutex_lock(&mutex);
265         if (data && pDMImpl->__pEvent)
266         {
267                 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
268                 pEventArg->__id = reqId;
269                 pEventArg->__state = STATE_DOWNLOADING;
270                 pEventArg->__received = received;
271
272                 unsigned long long total = 0;
273                 download_get_content_size(download_id, &total);
274                 pEventArg->__total = total;
275
276                 SysLog(NID_CNT, "OnProgress, id = %d, received = %lld, total = %lld", download_id, received, total);
277
278                 pDMImpl->__pEvent->Fire(*pEventArg);
279         }
280         pthread_mutex_unlock(&mutex);
281 }
282
283
284 _DownloadManagerImpl::_DownloadManagerImpl(void)
285         : __pEvent(null)
286 {
287 }
288
289 _DownloadManagerImpl::~_DownloadManagerImpl(void)
290 {
291         if (__pEvent)
292         {
293                 delete __pEvent;
294         }
295 }
296
297 void
298 _DownloadManagerImpl::InitSingleton(void)
299 {
300         unique_ptr<_DownloadManagerImpl> pImpl(new (std::nothrow) _DownloadManagerImpl);
301         SysTryReturnVoidResult(NID_CNT, pImpl != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
302
303         __pInstance = pImpl.release();
304
305         std::atexit(DestroySingleton);
306 }
307
308 void
309 _DownloadManagerImpl::DestroySingleton(void)
310 {
311         delete __pInstance;
312 }
313
314 _DownloadManagerImpl*
315 _DownloadManagerImpl::GetInstance(void)
316 {
317         static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
318         if (__pInstance == null)
319         {
320                 ClearLastResult();
321
322                 pthread_once(&onceBlock, InitSingleton);
323                 result r = GetLastResult();
324                 if(IsFailed(r))
325                 {
326                         onceBlock = PTHREAD_ONCE_INIT;
327                 }
328         }
329
330         return __pInstance;
331 }
332
333 result
334 _DownloadManagerImpl::Start(const DownloadRequest& request, RequestId& reqId)
335 {
336         SysLog(NID_CNT, "Start a download from Url = %ls, Path = %ls", request.GetUrl().GetPointer(), request.GetDirectoryPath().GetPointer());
337
338         result r = E_SUCCESS;
339
340         int ret = 0;
341         int download_id = 0;
342
343         String url = request.GetUrl();
344         String dirPath = request.GetDirectoryPath();
345         String fileName = request.GetFileName();
346         NetworkType networkType = (NetworkType)request.GetNetworkType();
347
348         SysTryReturnResult(NID_CNT, !url.IsEmpty(), E_INVALID_ARG, "The url of the download request is empty.");
349
350         // Create a download id
351         ret = download_create(&download_id);
352         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
353
354         // Set the url
355         unique_ptr<char[]> pUrl(_StringConverter::CopyToCharArrayN(url));
356
357         ret = download_set_url(download_id, pUrl.get());
358         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
359
360         //Set network type
361         if (networkType == NETWORK_ALL)
362         {
363                 ret = download_set_network_type(download_id, (download_network_type_e)DOWNLOAD_NETWORK_ALL);
364         }
365         else
366         {
367                 ret = download_set_network_type(download_id, (download_network_type_e)networkType);
368         }
369         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
370
371         //Set notification
372         ret = download_set_notification(download_id, request.IsNotificationEnabled());
373         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
374
375         //Set notification extra data
376         std::unique_ptr<IMapEnumerator> pMapEnum(const_cast< IMap* >(request.GetNotificationExtraData())->GetMapEnumeratorN());
377
378         while (pMapEnum->MoveNext() == E_SUCCESS)
379         {
380                 String* pMapKey = dynamic_cast<String*>(pMapEnum->GetKey());
381                 String* pMapValue = dynamic_cast<String*>(pMapEnum->GetValue());
382
383                 if (pMapKey && pMapValue)
384                 {
385                         unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(*pMapKey));
386                         const char* pValue = _StringConverter::CopyToCharArrayN(*pMapValue);
387
388                         ret = download_add_notification_extra_param(download_id, pKey.get(), &pValue, 1);
389                         delete[] pValue;
390                         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
391                 }
392         }
393
394         //Add http headers
395         IMap* pRequestHeader = _DownloadRequestImpl::GetInstance(&request)->GetRequestHeader();
396         std::unique_ptr<IMapEnumerator> pMapEnume(const_cast< IMap* >(pRequestHeader)->GetMapEnumeratorN());
397         while (pMapEnume->MoveNext() == E_SUCCESS)
398         {
399                 String* pMapKey = dynamic_cast<String*>(pMapEnume->GetKey());
400                 String* pMapValue = dynamic_cast<String*>(pMapEnume->GetValue());
401                 if (pMapKey && pMapValue)
402                 {
403                         unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(*pMapKey));
404                         unique_ptr<char[]> pValue(_StringConverter::CopyToCharArrayN(*pMapValue));
405
406                         ret = download_add_http_header_field(download_id, pKey.get(), pValue.get());
407                         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
408
409                 }
410         }
411
412         // Check the download path
413         if (!dirPath.IsEmpty())
414         {
415                 unique_ptr<char[]> pStr(_StringConverter::CopyToCharArrayN(dirPath));
416
417                 ret = access(pStr.get(), F_OK);
418                 if (ret == 0)
419                 {
420                         ret = access(pStr.get(), W_OK);
421                         SysTryReturnResult(NID_CNT, ret == 0, E_ILLEGAL_ACCESS, "Access to the requested path is denied due to insufficient permission.");
422                 }
423
424                 ret = download_set_destination(download_id, pStr.get());
425                 SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
426         }
427
428         // Set the file name
429         if (!fileName.IsEmpty())
430         {
431                 unique_ptr<char[]> pStr(_StringConverter::CopyToCharArrayN(fileName));
432
433                 ret = download_set_file_name(download_id, pStr.get());
434                 SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
435         }
436
437         // Set the callback functions
438         r = RegisterCallback((long)download_id);
439         SysTryReturnResult(NID_CNT, r == E_SUCCESS, E_SYSTEM, "The internal system service is not available.");
440
441         // Start the download request
442         ret = download_start(download_id);
443         SysTryCatch(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_PARAMETER, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
444         SysTryCatch(NID_CNT, ret >= 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The internal system service is not available. %d", ret);
445
446         // Set a request Id
447         reqId = (long)download_id;
448
449         return E_SUCCESS;
450
451 CATCH:
452         UnregisterCallback((long)download_id);
453
454         return r;
455 }
456
457 result
458 _DownloadManagerImpl::Pause(RequestId reqId)
459 {
460         int ret = 0;
461
462         // Pause the download request
463         ret = download_pause((int)reqId);
464         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_PARAMETER, E_INVALID_ARG, "There is no download request for the request.");
465         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, E_INVALID_ARG, "The request ID is not valid.");
466         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_STATE, E_INVALID_OPERATION, "The current download state is not downloading.");
467         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
468
469         return E_SUCCESS;
470 }
471
472 result
473 _DownloadManagerImpl::Resume(RequestId reqId)
474 {
475         int ret = 0;
476
477         // Set the callback functions
478         result r = RegisterCallback((int)reqId);
479         SysTryReturnResult(NID_CNT, r == E_SUCCESS, E_SYSTEM, "The internal system service is not available.");
480
481         // Resume the download request
482         ret = download_start((int)reqId);
483         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_PARAMETER, E_INVALID_ARG, "There is no download request for the request.");
484         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, E_INVALID_ARG, "The request ID is not valid.");
485         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_STATE, E_INVALID_OPERATION, "The current download state is not paused or has failed.");
486         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
487
488         return E_SUCCESS;
489 }
490
491 result
492 _DownloadManagerImpl::Cancel(RequestId reqId)
493 {
494         int ret = 0;
495
496         // Stop the download request
497         ret = download_cancel((int)reqId);
498         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_PARAMETER, E_INVALID_ARG, "There is no download request for the request.");
499         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, E_INVALID_ARG, "The request ID is not valid.");
500         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
501
502         return E_SUCCESS;
503 }
504
505 DownloadRequest*
506 _DownloadManagerImpl::GetDownloadRequestN(RequestId reqId)
507 {
508         result r = E_SUCCESS;
509         DownloadRequest* pRequest = null;
510         int ret = 0;
511         char* pUrl = null;
512         char* pPath = null;
513         bool notification = false;
514         int length = 0;
515         char** pFields = null;
516         char* pValue = null;
517         char* pFileName = null;
518         download_network_type_e netType = (download_network_type_e)DOWNLOAD_NETWORK_DATA_NETWORK;
519
520         ret = download_get_url(reqId, &pUrl);
521         SysTryCatch(NID_CNT, (ret != DOWNLOAD_ERROR_ID_NOT_FOUND) && (ret != DOWNLOAD_ERROR_INVALID_PARAMETER), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
522         ret = download_get_network_type(reqId, &netType);
523         SysTryCatch(NID_CNT, (ret != DOWNLOAD_ERROR_ID_NOT_FOUND) && (ret != DOWNLOAD_ERROR_INVALID_PARAMETER), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
524         ret = download_get_destination(reqId, &pPath);
525         SysTryCatch(NID_CNT, (ret != DOWNLOAD_ERROR_ID_NOT_FOUND) && (ret != DOWNLOAD_ERROR_INVALID_PARAMETER), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
526         ret = download_get_file_name(reqId, &pFileName);
527         SysTryCatch(NID_CNT, (ret != DOWNLOAD_ERROR_ID_NOT_FOUND) && (ret != DOWNLOAD_ERROR_INVALID_PARAMETER), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
528         ret = download_get_notification(reqId, &notification);
529         SysTryCatch(NID_CNT, (ret != DOWNLOAD_ERROR_ID_NOT_FOUND) && (ret != DOWNLOAD_ERROR_INVALID_PARAMETER), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
530         ret = download_get_http_header_field_list(reqId, &pFields, &length);
531         SysTryCatch(NID_CNT, (ret != DOWNLOAD_ERROR_ID_NOT_FOUND) && (ret != DOWNLOAD_ERROR_INVALID_PARAMETER), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
532         pRequest = new (std::nothrow) DownloadRequest(pUrl, pPath);
533         SysTryCatch(NID_CNT, pRequest != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
534         pRequest->SetFileName(pFileName);
535         pRequest->SetNotification(notification);
536         pRequest->SetNetworkType((DownloadNetworkType)netType);
537         //Get all the field values
538         for (int i = 0; i < length; i++)
539         {
540                 ret = download_get_http_header_field(reqId, pFields[i], &pValue);
541                 SysTryCatch(NID_CNT, (ret != DOWNLOAD_ERROR_ID_NOT_FOUND) && (ret != DOWNLOAD_ERROR_INVALID_PARAMETER), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
542                 pRequest->AddRequestHeader(pFields[i], pValue);
543                 free(pValue);
544                 free(pFields[i]);
545                 pValue = null;
546         }
547
548 CATCH:
549         free(pUrl);
550         free(pPath);
551         free(pFileName);
552         SetLastResult(r);
553         return pRequest;
554 }
555
556 result
557 _DownloadManagerImpl::GetMimeType(RequestId reqId, String& mimeType)
558 {
559         int ret = 0;
560         char* pStr = null;
561
562         ret = download_get_mime_type((int)reqId, &pStr);
563         SysTryReturnResult(NID_CNT, (ret != DOWNLOAD_ERROR_ID_NOT_FOUND) && (ret != DOWNLOAD_ERROR_INVALID_PARAMETER), E_INVALID_ARG, "There is no download request for the request ID.");
564         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_STATE, E_INVALID_OPERATION, "The current download state is not downloading or paused.");
565         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
566
567         mimeType = pStr;
568         delete[] pStr;
569
570         return E_SUCCESS;
571 }
572
573 int
574 _DownloadManagerImpl::GetState(RequestId reqId) const
575 {
576         int ret = 0;
577
578         download_state_e download_state = (download_state_e)SLP_STATE_NONE;
579         int state = STATE_NONE;
580
581         ret = download_get_state((int)reqId, &download_state);
582         SysTryReturn(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, STATE_NONE, E_INVALID_ARG, "[E_INVALID_ARG] The request ID is not valid.");
583         SysTryReturn(NID_CNT, ret >= 0, STATE_NONE, E_SYSTEM, "[E_SYSTEM] The internal system service is not available. %d", ret);
584
585         switch(download_state)
586         {
587                 case SLP_STATE_NONE:
588                         state = STATE_NONE;
589                         break;
590
591                 case SLP_STATE_READY:
592                         state = STATE_QUEUED;
593                         break;
594
595                 case SLP_STATE_QUEUED:
596                         state = STATE_QUEUED;
597                         break;
598
599                 case SLP_STATE_DOWNLOADING:
600                         state = STATE_DOWNLOADING;
601                         break;
602
603                 case SLP_STATE_PAUSED:
604                         state = STATE_PAUSED;
605                         break;
606
607                 case SLP_STATE_COMPLETED:
608                         state = STATE_COMPLETED;
609                         break;
610
611                 case SLP_STATE_CANCELLED:
612                         state = STATE_CANCELLED;
613                         break;
614
615                 case SLP_STATE_FAILED:
616                         state = STATE_FAILED;
617                         break;
618
619                 default:
620                         state = STATE_NONE;
621                         break;
622         }
623
624         SysLog(NID_CNT, "download_state = %d, state = %d", download_state, state);
625
626         return state;
627 }
628
629 result
630 _DownloadManagerImpl::GetProgress(RequestId reqId, int& progress)
631 {
632         return E_SUCCESS;
633 }
634
635 result
636 _DownloadManagerImpl::SetAllowedNetwork(unsigned long flags)
637 {
638         return E_SUCCESS;
639 }
640
641 void
642 _DownloadManagerImpl::SetDownloadListener(IDownloadListener* pListener)
643 {
644         pthread_mutex_lock(&mutex);
645
646         if (pListener != null)
647         {
648                 _DownloadEvent* pEvent = new (std::nothrow) _DownloadEvent();
649                 SysTryReturnVoidResult(NID_IO, pEvent != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
650
651                 pEvent->AddListener(*pListener);
652
653                 __pEvent = pEvent;
654         }
655         else
656         {
657                 if (__pEvent != null)
658                 {
659                         delete __pEvent;
660                 }
661
662                 __pEvent = null;
663         }
664
665         pthread_mutex_unlock(&mutex);
666 }
667
668 void
669 _DownloadManagerImpl::DestroyResources(RequestId reqId)
670 {
671         int ret = 0;
672
673         // Cancel the callback
674         UnregisterCallback(reqId);
675
676         // Remove the resource from url_download
677         ret = download_destroy((int)reqId);
678         SysTryLog(NID_CNT, ret >= 0, "url_download_destory fails %d", ret);
679 }
680
681 result
682 _DownloadManagerImpl::RegisterCallback(RequestId reqId)
683 {
684         int ret = 0;
685
686         ret = download_set_state_changed_cb(reqId, OnStateChanged, this);
687         SysTryCatch(NID_CNT, ret >= 0, , E_SYSTEM, "[E_SYSTEM] Fails to set state_changed_cb: %d, id = %d", ret, reqId);
688
689         ret = download_set_progress_cb(reqId, OnProgress, this);
690         SysTryCatch(NID_CNT, ret >= 0, , E_SYSTEM, "[E_SYSTEM] Fails to set progress_cb: %d, id = %d", ret, reqId);
691
692         return E_SUCCESS;
693
694 CATCH:
695         UnregisterCallback(reqId);
696
697         return E_SYSTEM;
698 }
699
700 void
701 _DownloadManagerImpl::UnregisterCallback(RequestId reqId)
702 {
703         int ret = 0;
704
705         ret = download_unset_state_changed_cb(reqId);
706         SysTryLog(NID_CNT, ret >= 0, "download_unset_state_changed_cb fails %d, id = %d", ret, reqId);
707
708         ret = download_unset_progress_cb(reqId);
709         SysTryLog(NID_CNT, ret >= 0, "download_unset_progress_cb fails %d, id = %d", ret, reqId);
710 }
711
712 result
713 _DownloadManagerImpl::ConvertToResult(int error)
714 {
715         result r = E_SUCCESS;
716         download_error_e download_error = (download_error_e)error;
717
718         SysLog(NID_CNT, "Download error = %d", download_error);
719
720         switch(download_error)
721         {
722                 case DOWNLOAD_ERROR_NONE:
723                         r = E_SUCCESS;
724                         break;
725
726                 case DOWNLOAD_ERROR_OUT_OF_MEMORY:
727                         r = E_OUT_OF_MEMORY;
728                         break;
729
730                 case DOWNLOAD_ERROR_IO_ERROR:
731                         r = E_SYSTEM;
732                         break;
733
734                 case DOWNLOAD_ERROR_INVALID_URL:
735                         r = E_INVALID_URL;
736                         break;
737
738                 case DOWNLOAD_ERROR_ID_NOT_FOUND:
739                         r = E_INVALID_ARG;
740                         break;
741
742                 case DOWNLOAD_ERROR_CONNECTION_FAILED:
743                 case DOWNLOAD_ERROR_NETWORK_UNREACHABLE:
744                         r = E_CONNECTION_FAILED;
745                         break;
746
747                 case DOWNLOAD_ERROR_CONNECTION_TIMED_OUT:
748                         r = E_TIMEOUT;
749                         break;
750
751                 case DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS:
752                         r = E_MAX_EXCEEDED;
753                         break;
754
755                 case DOWNLOAD_ERROR_NO_SPACE:
756                         r = E_STORAGE_FULL;
757                         break;
758
759                 case DOWNLOAD_ERROR_QUEUE_FULL:
760
761                 //case URL_DOWNLOAD_ERROR_INVALID_STATE:
762                 //case URL_DOWNLOAD_ERROR_INVALID_PARAMETER:
763                 //case URL_DOWNLOAD_ERROR_INVALID_DESTINATION:
764                 //case URL_DOWNLOAD_ERROR_ALREADY_COMPLETED:
765                 default:
766                         r = E_SYSTEM;
767         }
768
769         return r;
770 }
771
772 } } // Tizen::Content