Update change log and spec for wrt-plugins-tizen_0.4.13
[framework/web/wrt-plugins-tizen.git] / src / Download / DownloadManager.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 <glib.h>
19
20 #include <download.h>
21
22 #include <Logger.h>
23 #include <FilesystemUtils.h>
24
25 #include "DownloadState.h"
26 #include "DownloadNetworkType.h"
27 #include "DownloadManager.h"
28
29 namespace DeviceAPI {
30 namespace Download {
31
32 static std::string _get_download_error(int err)
33 {
34         bool success = false;
35     std::string msg = "";
36
37     switch (err) {
38         case DOWNLOAD_ERROR_INVALID_PARAMETER:
39             msg = "Invalid parameter";
40             break;
41         case DOWNLOAD_ERROR_OUT_OF_MEMORY:
42             msg = "Out of memory";
43             break;
44         case DOWNLOAD_ERROR_NETWORK_UNREACHABLE:
45             msg = "Network is unreachable";
46             break;
47         case DOWNLOAD_ERROR_CONNECTION_TIMED_OUT:
48             msg = "Http session time-out";
49             break;
50         case DOWNLOAD_ERROR_NO_SPACE:
51             msg = "No space left on device";
52             break;
53         case DOWNLOAD_ERROR_FIELD_NOT_FOUND:
54             msg = "Specified field not found";
55             break;
56         case DOWNLOAD_ERROR_INVALID_STATE:
57             msg = "Invalid state";
58             break;
59         case DOWNLOAD_ERROR_CONNECTION_FAILED:
60             msg = "Connection failed";
61             break;
62         case DOWNLOAD_ERROR_INVALID_URL:
63             msg = "Invalid URL";
64             break;
65         case DOWNLOAD_ERROR_INVALID_DESTINATION:
66             msg = "Invalid destination";
67             break;
68         case DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS:
69             msg = "Full of available simultaneous downloads";
70             break;
71         case DOWNLOAD_ERROR_QUEUE_FULL:
72             msg = "Full of available downloading items from server";
73             break;
74         case DOWNLOAD_ERROR_ALREADY_COMPLETED:
75             msg = "The download is already completed";
76             break;
77         case DOWNLOAD_ERROR_FILE_ALREADY_EXISTS:
78             msg = "It is failed to rename the downloaded file";
79             break;
80         case DOWNLOAD_ERROR_CANNOT_RESUME:
81             msg = "It cannot resume";
82             break;
83         case DOWNLOAD_ERROR_TOO_MANY_REDIRECTS:
84             msg = "In case of too may redirects from http response header";
85             break;
86         case DOWNLOAD_ERROR_UNHANDLED_HTTP_CODE:
87             msg = "The download cannot handle the http status value";
88             break;
89         case DOWNLOAD_ERROR_REQUEST_TIMEOUT:
90             msg = "There are no action after client create a download id";
91             break;
92         case DOWNLOAD_ERROR_RESPONSE_TIMEOUT:
93             msg = "It does not call start API in some time although the download is created";
94             break;
95         case DOWNLOAD_ERROR_SYSTEM_DOWN:
96             msg = "There are no response from client after rebooting download daemon";
97             break;
98         case DOWNLOAD_ERROR_ID_NOT_FOUND:
99             msg = "The download id is not existed in download service module";
100             break;
101         case DOWNLOAD_ERROR_NO_DATA:
102             msg = "No data because the set API is not called";
103             break;
104         case DOWNLOAD_ERROR_IO_ERROR:
105             msg = "Internal I/O error";
106             break;
107         case DOWNLOAD_ERROR_NONE:
108             success = true;
109             break;
110         default:
111             msg = "Unknown error";
112     }
113
114     if (!success) {
115         LogError("Platform error %d <%s>", err, msg.c_str());
116     }
117
118     return msg;
119 }
120
121 typedef struct {
122         int downloadId;
123         download_state_e state;
124         unsigned long long received;
125         void *user_data;
126 } DOWNLOAD_EVENT_DATA_T;
127
128
129 static gboolean downloadEventCB(void *data) {
130         int ret;
131
132         DOWNLOAD_EVENT_DATA_T *fnData = static_cast<DOWNLOAD_EVENT_DATA_T*>(data);
133
134         try {
135                 long downloadId = (long)fnData->downloadId;
136
137                 DownloadManager *thisObj = (DownloadManager*)fnData->user_data;
138                 if (!thisObj) {
139                         throw UnknownException("UserData is NULL.");
140                 }
141
142                 DownloadCallback *callback = thisObj->getCallbackFromMap(downloadId);
143                 if (!callback) {
144                         throw UnknownException("Callback could not found.");
145                 }
146
147                 switch(fnData->state) {
148                         case DOWNLOAD_STATE_QUEUED:
149                         {
150                                 callback->onprogress(downloadId, 0, 0);
151                                 break;
152                         }
153                         case DOWNLOAD_STATE_PAUSED:
154                         {
155                                 callback->onpaused(downloadId);
156                                 break;
157                         }
158                         case DOWNLOAD_STATE_DOWNLOADING:
159                         {
160                                 unsigned long long totalSize = 0;
161                                 ret = download_get_content_size(downloadId, &totalSize);
162                                 if (ret != DOWNLOAD_ERROR_NONE) {
163                                         throw UnknownException(("Platform error while getting total file size. " + _get_download_error(ret)).c_str());
164                                 }
165
166                                 callback->onprogress(downloadId, fnData->received, totalSize);
167                                 break;
168                         }
169                         case DOWNLOAD_STATE_COMPLETED:
170                         {
171                                 ret = download_unset_state_changed_cb(downloadId);
172                                 if (ret != DOWNLOAD_ERROR_NONE) {
173                                         throw UnknownException(("Platform error while unsetting state changed callback. " + _get_download_error(ret)).c_str());
174                                 }
175
176                                 ret = download_unset_progress_cb(downloadId);
177                                 if (ret != DOWNLOAD_ERROR_NONE) {
178                                         throw UnknownException(("Platform error while unsetting progress callback. " + _get_download_error(ret)).c_str());
179                                 }
180
181                                 char *fullPath = NULL;
182                                 ret = download_get_downloaded_file_path(downloadId, &fullPath);
183                                 if (ret != DOWNLOAD_ERROR_NONE || !fullPath) {
184                                         throw UnknownException(("Platform error while getting downloaded full path. " + _get_download_error(ret)).c_str());
185                                 }
186
187                                 ret = download_destroy(downloadId);
188                                 if (ret != DOWNLOAD_ERROR_NONE) {
189                                         LogWarning("Platform error while destroying download handle. downloadId=" << downloadId);
190                                 }
191
192                                 std::string virtualPath;
193                                 try {
194                                         virtualPath = DeviceAPI::Filesystem::Utils::toVirtualPath(NULL, fullPath);
195                                 } catch (...) {
196                                         LogWarning("Platform error while converting fullPath.");
197                                         virtualPath = fullPath;
198                                 }
199
200                                 callback->oncompleted(downloadId, virtualPath);
201                                 free(fullPath);
202
203                                 thisObj->removeCallbackFromMap(downloadId);
204                                 break;
205                         }
206                         case DOWNLOAD_STATE_FAILED:
207                         {
208                                 ret = download_unset_state_changed_cb(downloadId);
209                                 if (ret != DOWNLOAD_ERROR_NONE) {
210                                         throw UnknownException(("Platform error while unsetting state changed callback. " + _get_download_error(ret)).c_str());
211                                 }
212
213                                 ret = download_unset_progress_cb(downloadId);
214                                 if (ret != DOWNLOAD_ERROR_NONE) {
215                                         throw UnknownException(("Platform error while unsetting progress callback. " + _get_download_error(ret)).c_str());
216                                 }
217
218                                 int err = DOWNLOAD_ERROR_NONE;
219                                 std::string errMessage;
220                                 ret = download_get_error(downloadId, (download_error_e*)&err);
221                                 if (ret != DOWNLOAD_ERROR_NONE) {
222                                         LogWarning("Platform error while getting download error. ");
223                                 } else {
224                                         errMessage = _get_download_error(err);
225                                 }
226
227                                 ret = download_destroy(downloadId);
228                                 if (ret != DOWNLOAD_ERROR_NONE) {
229                                         LogWarning("Platform error while destroying download handle. downloadId=" << downloadId);
230                                 }
231
232                                 UnknownException error(errMessage.c_str());
233                                 callback->onfailed(downloadId, error);
234                                 thisObj->removeCallbackFromMap(downloadId);
235                                 break;
236                         }
237                         case DOWNLOAD_STATE_CANCELED:
238                         {
239                                 ret = download_unset_state_changed_cb(downloadId);
240                                 if (ret != DOWNLOAD_ERROR_NONE) {
241                                         throw UnknownException(("Platform error while unsetting state changed callback. " + _get_download_error(ret)).c_str());
242                                 }
243
244                                 ret = download_unset_progress_cb(downloadId);
245                                 if (ret != DOWNLOAD_ERROR_NONE) {
246                                         throw UnknownException(("Platform error while unsetting progress callback. " + _get_download_error(ret)).c_str());
247                                 }
248
249                                 ret = download_destroy(downloadId);
250                                 if (ret != DOWNLOAD_ERROR_NONE) {
251                                         LogWarning("Platform error while destroying download handle. downloadId=" << downloadId);
252                                 }
253
254                                 callback->oncanceled(downloadId);
255                                 thisObj->removeCallbackFromMap(downloadId);
256                                 break;
257                         }
258                         default:
259                                 LogWarning("State changed is ignored.");
260                                 break;
261                 }
262         } catch (const BasePlatformException &err) {
263                 LogError("download_state_changed_cb: %s", err.getMessage().c_str());
264         }
265
266         delete fnData;
267         return false;
268 }
269
270 static void download_state_changed_cb(int downloadId, download_state_e state, void *user_data)
271 {
272         LogDebug("download_state_changed_cb, downloadId=%d, state=%d", downloadId, (int)state);
273         DOWNLOAD_EVENT_DATA_T *data = new DOWNLOAD_EVENT_DATA_T;
274         data->downloadId = downloadId;
275         data->state = state;
276         data->received = 0;
277         data->user_data = user_data;
278
279         // download core f/w calls this callback function in another thread. 
280         // so we should use g_idle_add() to switch context to main thread.
281         g_idle_add(downloadEventCB, static_cast<void*>(data));
282 }
283
284 static void download_progress_cb(int downloadId, unsigned long long received, void *user_data)
285 {
286         LogDebug("download_progress_cb, downloadId=%d, received=%ld", downloadId, received);
287         DOWNLOAD_EVENT_DATA_T *data = new DOWNLOAD_EVENT_DATA_T;
288         data->downloadId = downloadId;
289         data->state = DOWNLOAD_STATE_DOWNLOADING;
290         data->received = received;
291         data->user_data = user_data;
292
293         // download core f/w calls this callback function in another thread. 
294         // so we should use g_idle_add() to switch context to main thread.
295         g_idle_add(downloadEventCB, static_cast<void*>(data));
296 }
297
298 DownloadManager::DownloadManager()
299 {
300 }
301
302 DownloadManager::~DownloadManager()
303 {
304 }
305
306 void DownloadManager::setCallbackToMap(long downloadId, DownloadCallback *callback)
307 {
308         DownloadCallback *value = mDownloadCallbacks[downloadId];
309         if (value) {
310                 delete value;
311         }
312         mDownloadCallbacks[downloadId] = callback;
313 }
314
315 DownloadCallback* DownloadManager::getCallbackFromMap(long downloadId)
316 {
317         return mDownloadCallbacks[downloadId];
318 }
319
320 void DownloadManager::removeCallbackFromMap(long downloadId) {
321         DownloadCallback *value = mDownloadCallbacks[downloadId];
322         mDownloadCallbacks.erase(downloadId);
323         if (value) {
324                 delete value;
325         }
326 }
327
328 long DownloadManager::start(DownloadRequest *request, DownloadCallback *downloadCallback)
329 {
330
331         int ret;
332         int downloadId = 0;
333
334         LogDebug("entered");
335
336         if (!request) {
337                 throw TypeMismatchException("request is NULL.");
338         }
339
340         std::string url = request->getUrl();
341         std::string destination = request->getDestination();
342         std::string fileName = request->getFileName();
343         std::string networkType = request->getNetworkType();
344         std::map<std::string, std::string> httpHeader = request->getHttpHeader();
345
346         LogDebug("url <%s>, destination <%s>, fileName <%s>", url.c_str(), destination.c_str(), fileName.c_str());
347
348         if (url.empty()) {
349                 throw InvalidValuesException("Invalid DownloadRequest.url.");
350         }
351
352         ret = download_create(&downloadId);
353         if (ret != DOWNLOAD_ERROR_NONE) {
354                 throw UnknownException(("Platform error while creating download. " + _get_download_error(ret)).c_str());
355         }
356
357         ret = download_set_url(downloadId, url.c_str());
358         if (ret != DOWNLOAD_ERROR_NONE) {
359                 throw UnknownException(("Platform error while setting url. " + _get_download_error(ret)).c_str());
360         }
361
362         if (!destination.empty()) {
363                 std::string fullPath;
364                 try {
365                         DeviceAPI::Filesystem::IPathPtr path = DeviceAPI::Filesystem::Utils::fromVirtualPath(NULL, destination);
366                         fullPath = path->getFullPath();
367                 } catch (...) {
368                         LogWarning("Converting virtual path is failed. [%s]", destination.c_str());
369                         fullPath = destination;
370                 }
371                 LogDebug("Converted FullPath = <%s>", fullPath.c_str());
372                 ret = download_set_destination(downloadId, fullPath.c_str());
373                 if (ret != DOWNLOAD_ERROR_NONE) {
374                         throw UnknownException(("Platform error while setting destination. " + _get_download_error(ret)).c_str());
375                 }
376         }
377
378         if (!fileName.empty()) {
379                 ret = download_set_file_name(downloadId, fileName.c_str());
380                 if (ret != DOWNLOAD_ERROR_NONE) {
381                         throw UnknownException(("Platform error while setting fileName. " + _get_download_error(ret)).c_str());
382                 }
383         }
384
385         ret = download_set_state_changed_cb(downloadId, download_state_changed_cb, this);
386         if (ret != DOWNLOAD_ERROR_NONE) {
387                 throw UnknownException(("Platform error while setting state changed callback. " + _get_download_error(ret)).c_str());
388         }
389
390         ret = download_set_progress_cb(downloadId, download_progress_cb, this);
391         if (ret != DOWNLOAD_ERROR_NONE) {
392                 throw UnknownException(("Platform error while setting progress callback. " + _get_download_error(ret)).c_str());
393         }
394
395         if (!networkType.empty()) {
396                 ret = DOWNLOAD_ERROR_NONE;
397                 if (networkType == TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_CELLULAR) {
398                         ret = download_set_network_type(downloadId, DOWNLOAD_NETWORK_DATA_NETWORK);
399                 } else if (networkType == TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_WIFI) {
400                         ret = download_set_network_type(downloadId, DOWNLOAD_NETWORK_WIFI);
401                 } else if (networkType == TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_ALL) {
402                         ret = download_set_network_type(downloadId, DOWNLOAD_NETWORK_ALL);
403                 } else {
404                         throw TypeMismatchException("Wrong DownloadNetworkType.");
405                 }
406                 if (ret != DOWNLOAD_ERROR_NONE) {
407                         throw UnknownException(("Platform error while setting network type. " + _get_download_error(ret)).c_str());
408                 }
409         }
410
411         std::map<std::string, std::string>::const_iterator iter;
412         for (iter = httpHeader.begin(); iter != httpHeader.end(); ++iter) {
413                 ret = download_add_http_header_field(downloadId, iter->first.c_str(), iter->second.c_str());
414                 if (ret != DOWNLOAD_ERROR_NONE) {
415                         throw UnknownException(("Platform error while setting http header fields. " + _get_download_error(ret)).c_str());
416                 }
417         }
418
419         ret = download_start(downloadId);
420         if (ret != DOWNLOAD_ERROR_NONE) {
421                 throw UnknownException(("Platform error while starting download. " + _get_download_error(ret)).c_str());
422         }
423
424         LogDebug("downloadId: %d", downloadId);
425
426         setCallbackToMap(downloadId, downloadCallback);
427
428         return downloadId;
429 }
430
431 void DownloadManager::cancel(long downloadId)
432 {
433         int ret;
434
435         LogDebug("entered. downloadId = %d", downloadId);
436
437         ret = download_cancel(downloadId);
438         if (ret != DOWNLOAD_ERROR_NONE) {
439                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
440                         throw NotFoundException("download id could not found.");
441                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
442                         throw InvalidValuesException("download id is not valid.");
443                 }
444                 throw UnknownException(("Platform error while canceling download. " + _get_download_error(ret)).c_str()); 
445         }
446 }
447
448 void DownloadManager::pause(long downloadId)
449 {
450         int ret;
451
452         LogDebug("entered. downloadId = %d", downloadId);
453
454         ret = download_pause(downloadId);
455         if (ret != DOWNLOAD_ERROR_NONE) {
456                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
457                         throw NotFoundException("download id could not found.");
458                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
459                         throw InvalidValuesException("download id is not valid.");
460                 }
461                 throw UnknownException(("Platform error while pausing download. " + _get_download_error(ret)).c_str()); 
462         }
463 }
464
465 void DownloadManager::resume(long downloadId)
466 {
467         int ret;
468
469         LogDebug("entered. downloadId = %d", downloadId);
470
471         ret = download_start(downloadId);
472         if (ret != DOWNLOAD_ERROR_NONE) {
473                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
474                         throw NotFoundException("download id could not found.");
475                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
476                         throw InvalidValuesException("download id is not valid.");
477                 }
478                 throw UnknownException(("Platform error while resuming download. " + _get_download_error(ret)).c_str()); 
479         }
480 }
481
482 std::string DownloadManager::getState(long downloadId)
483 {
484         int ret;
485         download_state_e state;
486         std::string result;
487
488         LogDebug("entered. downloadId = %d", downloadId);
489
490         ret = download_get_state(downloadId, &state);
491         if (ret != DOWNLOAD_ERROR_NONE) {
492                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
493                         throw NotFoundException("download id could not found.");
494                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
495                         throw InvalidValuesException("download id is not valid.");
496                 }
497                 throw UnknownException(("Platform error while getting state. " + _get_download_error(ret)).c_str()); 
498         }
499
500         switch (state) {
501                 case DOWNLOAD_STATE_READY:
502                 case DOWNLOAD_STATE_QUEUED:
503                         result = TIZEN_ENUM_DOWNLOAD_STATE_QUEUED;
504                         break;
505                 case DOWNLOAD_STATE_DOWNLOADING:
506                         result = TIZEN_ENUM_DOWNLOAD_STATE_DOWNLOADING;
507                         break;
508                 case DOWNLOAD_STATE_PAUSED:
509                         result = TIZEN_ENUM_DOWNLOAD_STATE_PAUSED;
510                         break;
511                 case DOWNLOAD_STATE_COMPLETED:
512                         result = TIZEN_ENUM_DOWNLOAD_STATE_COMPLETED;
513                         break;
514                 case DOWNLOAD_STATE_FAILED:
515                         result = TIZEN_ENUM_DOWNLOAD_STATE_FAILED;
516                         break;
517                 case DOWNLOAD_STATE_CANCELED:
518                         result = TIZEN_ENUM_DOWNLOAD_STATE_CANCELED;
519                         break;
520                 default:
521                         result = "undefined";
522                         LogWarning("Unknown DownloadState was returned.");
523                         break;
524         }
525
526         return result;
527 }
528
529 DownloadRequest* DownloadManager::getDownloadRequest(long downloadId)
530 {
531         int ret;
532         int i;
533
534         char *url = NULL;
535         char *destination = NULL;
536         char *fileName = NULL;
537         download_network_type_e networkTypeValue = DOWNLOAD_NETWORK_ALL;
538         char **fieldNames = NULL;
539         char *fieldValue = NULL;
540         int fieldLength = 0;
541
542         LogDebug("entered. downloadId = %d", downloadId);
543
544         ret = download_get_url(downloadId, &url);
545         if (ret != DOWNLOAD_ERROR_NONE) {
546                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
547                         throw NotFoundException("download id could not found.");
548                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
549                         throw InvalidValuesException("download id is not valid.");
550                 }
551                 throw UnknownException(("Platform error while getting url. " + _get_download_error(ret)).c_str());
552         }
553
554         ret = download_get_destination(downloadId, &destination);
555         if (ret != DOWNLOAD_ERROR_NONE && ret != DOWNLOAD_ERROR_NO_DATA) {
556                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
557                         throw NotFoundException("download id could not found.");
558                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
559                         throw InvalidValuesException("download id is not valid.");
560                 }
561                 throw UnknownException(("Platform error while getting destination. " + _get_download_error(ret)).c_str());
562         }
563
564         ret = download_get_file_name(downloadId, &fileName);
565         if (ret != DOWNLOAD_ERROR_NONE && ret != DOWNLOAD_ERROR_NO_DATA) {
566                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
567                         throw NotFoundException("download id could not found.");
568                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
569                         throw InvalidValuesException("download id is not valid.");
570                 }
571                 throw UnknownException(("Platform error while getting fileName. " + _get_download_error(ret)).c_str());
572         }
573
574         ret = download_get_network_type(downloadId, &networkTypeValue);
575         if (ret != DOWNLOAD_ERROR_NONE && ret != DOWNLOAD_ERROR_NO_DATA) {
576                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
577                         throw NotFoundException("download id could not found.");
578                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
579                         throw InvalidValuesException("download id is not valid.");
580                 }
581                 throw UnknownException(("Platform error while getting network type. " + _get_download_error(ret)).c_str());
582         }
583
584         ret = download_get_http_header_field_list(downloadId, &fieldNames, &fieldLength);
585         if (ret != DOWNLOAD_ERROR_NONE && ret != DOWNLOAD_ERROR_NO_DATA) {
586                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
587                         throw NotFoundException("download id could not found.");
588                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
589                         throw InvalidValuesException("download id is not valid.");
590                 }
591                 throw UnknownException(("Platform error while getting http header fields. " + _get_download_error(ret)).c_str());
592         }
593
594         std::map<std::string, std::string> httpHeader;
595         for (i = 0; i < fieldLength; i++) {
596                 ret = download_get_http_header_field(downloadId, fieldNames[i], &fieldValue);
597                 if (ret != DOWNLOAD_ERROR_NONE) {
598                         LogWarning("Platform error while getting http header field. " << _get_download_error(ret));
599                 }
600                 httpHeader.insert(make_pair(std::string(fieldNames[i]), std::string(fieldValue)));
601                 free(fieldNames[i]);
602                 free(fieldValue);
603         }
604         free(fieldNames);
605
606         DownloadRequest *request = new DownloadRequest();
607
608         if (url) {
609                 request->setUrl(url);
610                 free(url);
611         }
612
613         if (destination) {
614                 std::string virtualPath;
615                 try {
616                         virtualPath = DeviceAPI::Filesystem::Utils::toVirtualPath(NULL, destination);
617                 } catch (...) {
618                         LogWarning("Platform error while converting destination path.");
619                         virtualPath = destination;
620                 }
621                 request->setDestination(virtualPath);
622                 free(destination);
623         }
624
625         if (fileName) {
626                 request->setFileName(fileName);
627                 free(fileName);
628         }
629
630         switch(networkTypeValue) {
631         case DOWNLOAD_NETWORK_DATA_NETWORK:
632                 request->setNetworkType(TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_CELLULAR);
633                 break;
634         case DOWNLOAD_NETWORK_WIFI:
635                 request->setNetworkType(TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_WIFI);
636                 break;
637         default:
638                 request->setNetworkType(TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_ALL);
639                 break;
640         }
641
642         if (fieldLength) {
643                 request->setHttpHeader(httpHeader);
644         }
645
646
647         return request;
648 }
649
650 std::string DownloadManager::getMIMEType(long downloadId)
651 {
652         int ret;
653         char *mimeType = NULL;
654         std::string result("");
655
656         LogDebug("entered. downloadId = %d", downloadId);
657
658         ret = download_get_mime_type(downloadId, &mimeType);
659         if (ret != DOWNLOAD_ERROR_NONE) {
660                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
661                         throw NotFoundException("download id could not found.");
662                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
663                         throw InvalidValuesException("download id is not valid.");
664                 } else if (ret == DOWNLOAD_ERROR_NO_DATA) {
665                         result = "";
666                 } else {
667                         throw UnknownException(("Platform error while getting MIME type. " + _get_download_error(ret)).c_str()); 
668                 }
669         } else {
670                 result = mimeType;
671         }
672
673         if (mimeType) {
674                 free(mimeType);
675         }
676
677         return result;
678 }
679
680 void DownloadManager::setListener(long downloadId, DownloadCallback *downloadCallback)
681 {
682         int ret;
683
684         LogDebug("entered. downloadId = %d", downloadId);
685
686         ret = download_set_state_changed_cb(downloadId, download_state_changed_cb, this);
687         if (ret != DOWNLOAD_ERROR_NONE) {
688                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
689                         throw NotFoundException("download id could not found.");
690                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
691                         throw InvalidValuesException("download id is not valid.");
692                 }
693                 throw UnknownException(("Platform error while setting state changed callback. " + _get_download_error(ret)).c_str());
694         }
695
696         ret = download_set_progress_cb(downloadId, download_progress_cb, this);
697         if (ret != DOWNLOAD_ERROR_NONE) {
698                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
699                         throw NotFoundException("download id could not found.");
700                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
701                         throw InvalidValuesException("download id is not valid.");
702                 }
703                 throw UnknownException(("Platform error while setting progress callback. " + _get_download_error(ret)).c_str());
704         }
705
706         setCallbackToMap(downloadId, downloadCallback);
707 }
708
709 } // Download
710 } // DeviceAPI