Fix : The exception handling according to the situation
[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         ret = RegisterCallback((long)download_id);
439         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
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         result r = E_SUCCESS;
477
478         // Set the callback functions
479         ret = RegisterCallback((int)reqId);
480         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_PARAMETER, E_INVALID_ARG, "There is no download request for the request.");
481         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, E_INVALID_ARG, "The request ID is not valid.");
482         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
483
484         // Resume the download request
485         ret = download_start((int)reqId);
486         SysTryCatch(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_PARAMETER, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] There is no download request for the request.");
487         SysTryCatch(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The request ID is not valid.");
488         SysTryCatch(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_STATE, r = E_INVALID_OPERATION, E_INVALID_OPERATION, "[E_INVALID_OPERATION] The current download state is not paused or has failed.");
489         SysTryCatch(NID_CNT, ret >= 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The internal system service is not available. %d", ret);
490
491         return E_SUCCESS;
492
493 CATCH:
494         UnregisterCallback((int)reqId);
495
496         return r;
497 }
498
499 result
500 _DownloadManagerImpl::Cancel(RequestId reqId)
501 {
502         int ret = 0;
503
504         // Stop the download request
505         ret = download_cancel((int)reqId);
506         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_PARAMETER, E_INVALID_ARG, "There is no download request for the request.");
507         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, E_INVALID_ARG, "The request ID is not valid.");
508         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
509
510         return E_SUCCESS;
511 }
512
513 DownloadRequest*
514 _DownloadManagerImpl::GetDownloadRequestN(RequestId reqId)
515 {
516         result r = E_SUCCESS;
517         DownloadRequest* pRequest = null;
518         int ret = 0;
519         char* pUrl = null;
520         char* pPath = null;
521         bool notification = false;
522         int length = 0;
523         char** pFields = null;
524         char* pValue = null;
525         char* pFileName = null;
526         download_network_type_e netType = (download_network_type_e)DOWNLOAD_NETWORK_DATA_NETWORK;
527
528         ret = download_get_url(reqId, &pUrl);
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_network_type(reqId, &netType);
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         ret = download_get_destination(reqId, &pPath);
533         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");
534         ret = download_get_file_name(reqId, &pFileName);
535         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");
536         ret = download_get_notification(reqId, &notification);
537         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");
538         ret = download_get_http_header_field_list(reqId, &pFields, &length);
539         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");
540         pRequest = new (std::nothrow) DownloadRequest(pUrl, pPath);
541         SysTryCatch(NID_CNT, pRequest != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
542         pRequest->SetFileName(pFileName);
543         pRequest->SetNotification(notification);
544         pRequest->SetNetworkType((DownloadNetworkType)netType);
545         //Get all the field values
546         for (int i = 0; i < length; i++)
547         {
548                 ret = download_get_http_header_field(reqId, pFields[i], &pValue);
549                 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");
550                 pRequest->AddRequestHeader(pFields[i], pValue);
551                 free(pValue);
552                 free(pFields[i]);
553                 pValue = null;
554         }
555
556 CATCH:
557         free(pUrl);
558         free(pPath);
559         free(pFileName);
560         SetLastResult(r);
561         return pRequest;
562 }
563
564 result
565 _DownloadManagerImpl::GetMimeType(RequestId reqId, String& mimeType)
566 {
567         int ret = 0;
568         char* pStr = null;
569
570         ret = download_get_mime_type((int)reqId, &pStr);
571         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.");
572         SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_STATE, E_INVALID_OPERATION, "The current download state is not downloading or paused.");
573         SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
574
575         mimeType = pStr;
576         delete[] pStr;
577
578         return E_SUCCESS;
579 }
580
581 int
582 _DownloadManagerImpl::GetState(RequestId reqId) const
583 {
584         int ret = 0;
585
586         download_state_e download_state = (download_state_e)SLP_STATE_NONE;
587         int state = STATE_NONE;
588
589         ret = download_get_state((int)reqId, &download_state);
590         SysTryReturn(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, STATE_NONE, E_INVALID_ARG, "[E_INVALID_ARG] The request ID is not valid.");
591         SysTryReturn(NID_CNT, ret >= 0, STATE_NONE, E_SYSTEM, "[E_SYSTEM] The internal system service is not available. %d", ret);
592
593         switch(download_state)
594         {
595                 case SLP_STATE_NONE:
596                         state = STATE_NONE;
597                         break;
598
599                 case SLP_STATE_READY:
600                         state = STATE_QUEUED;
601                         break;
602
603                 case SLP_STATE_QUEUED:
604                         state = STATE_QUEUED;
605                         break;
606
607                 case SLP_STATE_DOWNLOADING:
608                         state = STATE_DOWNLOADING;
609                         break;
610
611                 case SLP_STATE_PAUSED:
612                         state = STATE_PAUSED;
613                         break;
614
615                 case SLP_STATE_COMPLETED:
616                         state = STATE_COMPLETED;
617                         break;
618
619                 case SLP_STATE_CANCELLED:
620                         state = STATE_CANCELLED;
621                         break;
622
623                 case SLP_STATE_FAILED:
624                         state = STATE_FAILED;
625                         break;
626
627                 default:
628                         state = STATE_NONE;
629                         break;
630         }
631
632         SysLog(NID_CNT, "download_state = %d, state = %d", download_state, state);
633
634         return state;
635 }
636
637 result
638 _DownloadManagerImpl::GetProgress(RequestId reqId, int& progress)
639 {
640         return E_SUCCESS;
641 }
642
643 result
644 _DownloadManagerImpl::SetAllowedNetwork(unsigned long flags)
645 {
646         return E_SUCCESS;
647 }
648
649 void
650 _DownloadManagerImpl::SetDownloadListener(IDownloadListener* pListener)
651 {
652         pthread_mutex_lock(&mutex);
653
654         if (pListener != null)
655         {
656                 _DownloadEvent* pEvent = new (std::nothrow) _DownloadEvent();
657                 SysTryReturnVoidResult(NID_IO, pEvent != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
658
659                 pEvent->AddListener(*pListener);
660
661                 __pEvent = pEvent;
662         }
663         else
664         {
665                 if (__pEvent != null)
666                 {
667                         delete __pEvent;
668                 }
669
670                 __pEvent = null;
671         }
672
673         pthread_mutex_unlock(&mutex);
674 }
675
676 void
677 _DownloadManagerImpl::DestroyResources(RequestId reqId)
678 {
679         int ret = 0;
680
681         // Cancel the callback
682         UnregisterCallback(reqId);
683
684         // Remove the resource from url_download
685         ret = download_destroy((int)reqId);
686         SysTryLog(NID_CNT, ret >= 0, "url_download_destory fails %d", ret);
687 }
688
689 int
690 _DownloadManagerImpl::RegisterCallback(RequestId reqId)
691 {
692         int ret = 0;
693
694         ret = download_set_state_changed_cb(reqId, OnStateChanged, this);
695         SysTryCatch(NID_CNT, ret >= 0, , E_INVALID_ARG, "[E_INVALID_ARG] Fails to set state_changed_cb: %d, id = %d", ret, reqId);
696
697         ret = download_set_progress_cb(reqId, OnProgress, this);
698         SysTryCatch(NID_CNT, ret >= 0, , E_INVALID_ARG, "[E_INVALID_ARG] Fails to set progress_cb: %d, id = %d", ret, reqId);
699
700         return DOWNLOAD_ERROR_NONE;
701
702 CATCH:
703         UnregisterCallback(reqId);
704
705         return ret;
706 }
707
708 void
709 _DownloadManagerImpl::UnregisterCallback(RequestId reqId)
710 {
711         int ret = 0;
712
713         ret = download_unset_state_changed_cb(reqId);
714         SysTryLog(NID_CNT, ret >= 0, "download_unset_state_changed_cb fails %d, id = %d", ret, reqId);
715
716         ret = download_unset_progress_cb(reqId);
717         SysTryLog(NID_CNT, ret >= 0, "download_unset_progress_cb fails %d, id = %d", ret, reqId);
718 }
719
720 result
721 _DownloadManagerImpl::ConvertToResult(int error)
722 {
723         result r = E_SUCCESS;
724         download_error_e download_error = (download_error_e)error;
725
726         SysLog(NID_CNT, "Download error = %d", download_error);
727
728         switch(download_error)
729         {
730                 case DOWNLOAD_ERROR_NONE:
731                         r = E_SUCCESS;
732                         break;
733
734                 case DOWNLOAD_ERROR_OUT_OF_MEMORY:
735                         r = E_OUT_OF_MEMORY;
736                         break;
737
738                 case DOWNLOAD_ERROR_IO_ERROR:
739                         r = E_SYSTEM;
740                         break;
741
742                 case DOWNLOAD_ERROR_INVALID_URL:
743                         r = E_INVALID_URL;
744                         break;
745
746                 case DOWNLOAD_ERROR_ID_NOT_FOUND:
747                         r = E_INVALID_ARG;
748                         break;
749
750                 case DOWNLOAD_ERROR_CONNECTION_FAILED:
751                 case DOWNLOAD_ERROR_NETWORK_UNREACHABLE:
752                         r = E_CONNECTION_FAILED;
753                         break;
754
755                 case DOWNLOAD_ERROR_CONNECTION_TIMED_OUT:
756                         r = E_TIMEOUT;
757                         break;
758
759                 case DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS:
760                         r = E_MAX_EXCEEDED;
761                         break;
762
763                 case DOWNLOAD_ERROR_NO_SPACE:
764                         r = E_STORAGE_FULL;
765                         break;
766
767                 case DOWNLOAD_ERROR_QUEUE_FULL:
768
769                 //case URL_DOWNLOAD_ERROR_INVALID_STATE:
770                 //case URL_DOWNLOAD_ERROR_INVALID_PARAMETER:
771                 //case URL_DOWNLOAD_ERROR_INVALID_DESTINATION:
772                 //case URL_DOWNLOAD_ERROR_ALREADY_COMPLETED:
773                 default:
774                         r = E_SYSTEM;
775         }
776
777         return r;
778 }
779
780 } } // Tizen::Content