8542b43f32edd7b22af75c637c6c0e44543f1b88
[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                                 std::string virtualPath;
188                                 try {
189                                         virtualPath = DeviceAPI::Filesystem::Utils::toVirtualPath(NULL, fullPath);
190                                 } catch (...) {
191                                         LogWarning("Platform error while converting fullPath.");
192                                         virtualPath = fullPath;
193                                 }
194
195                                 callback->oncompleted(downloadId, virtualPath);
196                                 free(fullPath);
197
198                                 thisObj->removeCallbackFromMap(downloadId);
199                                 break;
200                         }
201                         case DOWNLOAD_STATE_FAILED:
202                         {
203                                 ret = download_unset_state_changed_cb(downloadId);
204                                 if (ret != DOWNLOAD_ERROR_NONE) {
205                                         throw UnknownException(("Platform error while unsetting state changed callback. " + _get_download_error(ret)).c_str());
206                                 }
207
208                                 ret = download_unset_progress_cb(downloadId);
209                                 if (ret != DOWNLOAD_ERROR_NONE) {
210                                         throw UnknownException(("Platform error while unsetting progress callback. " + _get_download_error(ret)).c_str());
211                                 }
212
213                                 int err = DOWNLOAD_ERROR_NONE;
214                                 std::string errMessage;
215                                 ret = download_get_error(downloadId, (download_error_e*)&err);
216                                 if (ret != DOWNLOAD_ERROR_NONE) {
217                                         LogWarning("Platform error while getting download error. ");
218                                 } else {
219                                         errMessage = _get_download_error(err);
220                                 }
221
222                                 UnknownException error(errMessage.c_str());
223                                 callback->onfailed(downloadId, error);
224                                 thisObj->removeCallbackFromMap(downloadId);
225                                 break;
226                         }
227                         case DOWNLOAD_STATE_CANCELED:
228                         {
229                                 ret = download_unset_state_changed_cb(downloadId);
230                                 if (ret != DOWNLOAD_ERROR_NONE) {
231                                         throw UnknownException(("Platform error while unsetting state changed callback. " + _get_download_error(ret)).c_str());
232                                 }
233
234                                 ret = download_unset_progress_cb(downloadId);
235                                 if (ret != DOWNLOAD_ERROR_NONE) {
236                                         throw UnknownException(("Platform error while unsetting progress callback. " + _get_download_error(ret)).c_str());
237                                 }
238
239                                 callback->oncanceled(downloadId);
240                                 thisObj->removeCallbackFromMap(downloadId);
241                                 break;
242                         }
243                         default:
244                                 LogWarning("State changed is ignored.");
245                                 break;
246                 }
247         } catch (const BasePlatformException &err) {
248                 LogError("download_state_changed_cb: %s", err.getMessage().c_str());
249         }
250
251         delete fnData;
252         return false;
253 }
254
255 static void download_state_changed_cb(int downloadId, download_state_e state, void *user_data)
256 {
257         LogDebug("download_state_changed_cb, downloadId=%d, state=%d", downloadId, (int)state);
258         DOWNLOAD_EVENT_DATA_T *data = new DOWNLOAD_EVENT_DATA_T;
259         data->downloadId = downloadId;
260         data->state = state;
261         data->received = 0;
262         data->user_data = user_data;
263
264         // download core f/w calls this callback function in another thread. 
265         // so we should use g_idle_add() to switch context to main thread.
266         g_idle_add(downloadEventCB, static_cast<void*>(data));
267 }
268
269 static void download_progress_cb(int downloadId, unsigned long long received, void *user_data)
270 {
271         LogDebug("download_progress_cb, downloadId=%d, received=%ld", downloadId, received);
272         DOWNLOAD_EVENT_DATA_T *data = new DOWNLOAD_EVENT_DATA_T;
273         data->downloadId = downloadId;
274         data->state = DOWNLOAD_STATE_DOWNLOADING;
275         data->received = received;
276         data->user_data = user_data;
277
278         // download core f/w calls this callback function in another thread. 
279         // so we should use g_idle_add() to switch context to main thread.
280         g_idle_add(downloadEventCB, static_cast<void*>(data));
281 }
282
283 DownloadManager::DownloadManager()
284 {
285 }
286
287 DownloadManager::~DownloadManager()
288 {
289 }
290
291 void DownloadManager::setCallbackToMap(long downloadId, DownloadCallback *callback)
292 {
293         DownloadCallback *value = mDownloadCallbacks[downloadId];
294         if (value) {
295                 delete value;
296         }
297         mDownloadCallbacks[downloadId] = callback;
298 }
299
300 DownloadCallback* DownloadManager::getCallbackFromMap(long downloadId)
301 {
302         return mDownloadCallbacks[downloadId];
303 }
304
305 void DownloadManager::removeCallbackFromMap(long downloadId) {
306         DownloadCallback *value = mDownloadCallbacks[downloadId];
307         mDownloadCallbacks.erase(downloadId);
308         if (value) {
309                 delete value;
310         }
311 }
312
313 long DownloadManager::start(DownloadRequest *request, DownloadCallback *downloadCallback)
314 {
315
316         int ret;
317         int downloadId = 0;
318
319         LogDebug("entered");
320
321         if (!request) {
322                 throw TypeMismatchException("request is NULL.");
323         }
324
325         std::string url = request->getUrl();
326         std::string destination = request->getDestination();
327         std::string fileName = request->getFileName();
328         std::string networkType = request->getNetworkType();
329         std::map<std::string, std::string> httpHeader = request->getHttpHeader();
330
331         LogDebug("url <%s>, destination <%s>, fileName <%s>", url.c_str(), destination.c_str(), fileName.c_str());
332
333         if (url.empty()) {
334                 throw InvalidValuesException("Invalid DownloadRequest.url.");
335         }
336
337         ret = download_create(&downloadId);
338         if (ret != DOWNLOAD_ERROR_NONE) {
339                 throw UnknownException(("Platform error while creating download. " + _get_download_error(ret)).c_str());
340         }
341
342         ret = download_set_url(downloadId, url.c_str());
343         if (ret != DOWNLOAD_ERROR_NONE) {
344                 throw UnknownException(("Platform error while setting url. " + _get_download_error(ret)).c_str());
345         }
346
347         if (!destination.empty()) {
348                 std::string fullPath;
349                 try {
350                         DeviceAPI::Filesystem::IPathPtr path = DeviceAPI::Filesystem::Utils::fromVirtualPath(NULL, destination);
351                         fullPath = path->getFullPath();
352                 } catch (...) {
353                         LogWarning("Converting virtual path is failed. [%s]", destination.c_str());
354                         fullPath = destination;
355                 }
356                 LogDebug("Converted FullPath = <%s>", fullPath.c_str());
357                 ret = download_set_destination(downloadId, fullPath.c_str());
358                 if (ret != DOWNLOAD_ERROR_NONE) {
359                         throw UnknownException(("Platform error while setting destination. " + _get_download_error(ret)).c_str());
360                 }
361         }
362
363         if (!fileName.empty()) {
364                 ret = download_set_file_name(downloadId, fileName.c_str());
365                 if (ret != DOWNLOAD_ERROR_NONE) {
366                         throw UnknownException(("Platform error while setting fileName. " + _get_download_error(ret)).c_str());
367                 }
368         }
369
370         ret = download_set_state_changed_cb(downloadId, download_state_changed_cb, this);
371         if (ret != DOWNLOAD_ERROR_NONE) {
372                 throw UnknownException(("Platform error while setting state changed callback. " + _get_download_error(ret)).c_str());
373         }
374
375         ret = download_set_progress_cb(downloadId, download_progress_cb, this);
376         if (ret != DOWNLOAD_ERROR_NONE) {
377                 throw UnknownException(("Platform error while setting progress callback. " + _get_download_error(ret)).c_str());
378         }
379
380         if (!networkType.empty()) {
381                 ret = DOWNLOAD_ERROR_NONE;
382                 if (networkType == TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_CELLULAR) {
383                         ret = download_set_network_type(downloadId, DOWNLOAD_NETWORK_DATA_NETWORK);
384                 } else if (networkType == TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_WIFI) {
385                         ret = download_set_network_type(downloadId, DOWNLOAD_NETWORK_WIFI);
386                 } else if (networkType == TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_ALL) {
387                         ret = download_set_network_type(downloadId, DOWNLOAD_NETWORK_ALL);
388                 } else {
389                         throw TypeMismatchException("Wrong DownloadNetworkType.");
390                 }
391                 if (ret != DOWNLOAD_ERROR_NONE) {
392                         throw UnknownException(("Platform error while setting network type. " + _get_download_error(ret)).c_str());
393                 }
394         }
395
396         std::map<std::string, std::string>::const_iterator iter;
397         for (iter = httpHeader.begin(); iter != httpHeader.end(); ++iter) {
398                 ret = download_add_http_header_field(downloadId, iter->first.c_str(), iter->second.c_str());
399                 if (ret != DOWNLOAD_ERROR_NONE) {
400                         throw UnknownException(("Platform error while setting http header fields. " + _get_download_error(ret)).c_str());
401                 }
402         }
403
404         ret = download_start(downloadId);
405         if (ret != DOWNLOAD_ERROR_NONE) {
406                 throw UnknownException(("Platform error while starting download. " + _get_download_error(ret)).c_str());
407         }
408
409         LogDebug("downloadId: %d", downloadId);
410
411         setCallbackToMap(downloadId, downloadCallback);
412
413         return downloadId;
414 }
415
416 void DownloadManager::cancel(long downloadId)
417 {
418         int ret;
419
420         LogDebug("entered. downloadId = %d", downloadId);
421
422         ret = download_cancel(downloadId);
423         if (ret != DOWNLOAD_ERROR_NONE) {
424                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
425                         throw NotFoundException("download id could not found.");
426                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
427                         throw InvalidValuesException("download id is not valid.");
428                 }
429                 throw UnknownException(("Platform error while canceling download. " + _get_download_error(ret)).c_str()); 
430         }
431 }
432
433 void DownloadManager::pause(long downloadId)
434 {
435         int ret;
436
437         LogDebug("entered. downloadId = %d", downloadId);
438
439         ret = download_pause(downloadId);
440         if (ret != DOWNLOAD_ERROR_NONE) {
441                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
442                         throw NotFoundException("download id could not found.");
443                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
444                         throw InvalidValuesException("download id is not valid.");
445                 }
446                 throw UnknownException(("Platform error while pausing download. " + _get_download_error(ret)).c_str()); 
447         }
448 }
449
450 void DownloadManager::resume(long downloadId)
451 {
452         int ret;
453
454         LogDebug("entered. downloadId = %d", downloadId);
455
456         ret = download_start(downloadId);
457         if (ret != DOWNLOAD_ERROR_NONE) {
458                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
459                         throw NotFoundException("download id could not found.");
460                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
461                         throw InvalidValuesException("download id is not valid.");
462                 }
463                 throw UnknownException(("Platform error while resuming download. " + _get_download_error(ret)).c_str()); 
464         }
465 }
466
467 std::string DownloadManager::getState(long downloadId)
468 {
469         int ret;
470         download_state_e state;
471         std::string result;
472
473         LogDebug("entered. downloadId = %d", downloadId);
474
475         ret = download_get_state(downloadId, &state);
476         if (ret != DOWNLOAD_ERROR_NONE) {
477                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
478                         throw NotFoundException("download id could not found.");
479                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
480                         throw InvalidValuesException("download id is not valid.");
481                 }
482                 throw UnknownException(("Platform error while getting state. " + _get_download_error(ret)).c_str()); 
483         }
484
485         switch (state) {
486                 case DOWNLOAD_STATE_READY:
487                 case DOWNLOAD_STATE_QUEUED:
488                         result = TIZEN_ENUM_DOWNLOAD_STATE_QUEUED;
489                         break;
490                 case DOWNLOAD_STATE_DOWNLOADING:
491                         result = TIZEN_ENUM_DOWNLOAD_STATE_DOWNLOADING;
492                         break;
493                 case DOWNLOAD_STATE_PAUSED:
494                         result = TIZEN_ENUM_DOWNLOAD_STATE_PAUSED;
495                         break;
496                 case DOWNLOAD_STATE_COMPLETED:
497                         result = TIZEN_ENUM_DOWNLOAD_STATE_COMPLETED;
498                         break;
499                 case DOWNLOAD_STATE_FAILED:
500                         result = TIZEN_ENUM_DOWNLOAD_STATE_FAILED;
501                         break;
502                 case DOWNLOAD_STATE_CANCELED:
503                         result = TIZEN_ENUM_DOWNLOAD_STATE_CANCELED;
504                         break;
505                 default:
506                         result = "undefined";
507                         LogWarning("Unknown DownloadState was returned.");
508                         break;
509         }
510
511         return result;
512 }
513
514 DownloadRequest* DownloadManager::getDownloadRequest(long downloadId)
515 {
516         int ret;
517         int i;
518
519         char *url = NULL;
520         char *destination = NULL;
521         char *fileName = NULL;
522         download_network_type_e networkTypeValue = DOWNLOAD_NETWORK_ALL;
523         char **fieldNames = NULL;
524         char *fieldValue = NULL;
525         int fieldLength = 0;
526
527         LogDebug("entered. downloadId = %d", downloadId);
528
529         ret = download_get_url(downloadId, &url);
530         if (ret != DOWNLOAD_ERROR_NONE) {
531                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
532                         throw NotFoundException("download id could not found.");
533                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
534                         throw InvalidValuesException("download id is not valid.");
535                 }
536                 throw UnknownException(("Platform error while getting url. " + _get_download_error(ret)).c_str());
537         }
538
539         ret = download_get_destination(downloadId, &destination);
540         if (ret != DOWNLOAD_ERROR_NONE && ret != DOWNLOAD_ERROR_NO_DATA) {
541                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
542                         throw NotFoundException("download id could not found.");
543                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
544                         throw InvalidValuesException("download id is not valid.");
545                 }
546                 throw UnknownException(("Platform error while getting destination. " + _get_download_error(ret)).c_str());
547         }
548
549         ret = download_get_file_name(downloadId, &fileName);
550         if (ret != DOWNLOAD_ERROR_NONE && ret != DOWNLOAD_ERROR_NO_DATA) {
551                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
552                         throw NotFoundException("download id could not found.");
553                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
554                         throw InvalidValuesException("download id is not valid.");
555                 }
556                 throw UnknownException(("Platform error while getting fileName. " + _get_download_error(ret)).c_str());
557         }
558
559         ret = download_get_network_type(downloadId, &networkTypeValue);
560         if (ret != DOWNLOAD_ERROR_NONE && ret != DOWNLOAD_ERROR_NO_DATA) {
561                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
562                         throw NotFoundException("download id could not found.");
563                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
564                         throw InvalidValuesException("download id is not valid.");
565                 }
566                 throw UnknownException(("Platform error while getting network type. " + _get_download_error(ret)).c_str());
567         }
568
569         ret = download_get_http_header_field_list(downloadId, &fieldNames, &fieldLength);
570         if (ret != DOWNLOAD_ERROR_NONE && ret != DOWNLOAD_ERROR_NO_DATA) {
571                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
572                         throw NotFoundException("download id could not found.");
573                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
574                         throw InvalidValuesException("download id is not valid.");
575                 }
576                 throw UnknownException(("Platform error while getting http header fields. " + _get_download_error(ret)).c_str());
577         }
578
579         std::map<std::string, std::string> httpHeader;
580         for (i = 0; i < fieldLength; i++) {
581                 ret = download_get_http_header_field(downloadId, fieldNames[i], &fieldValue);
582                 if (ret != DOWNLOAD_ERROR_NONE) {
583                         LogWarning("Platform error while getting http header field. " << _get_download_error(ret));
584                 }
585                 httpHeader.insert(make_pair(std::string(fieldNames[i]), std::string(fieldValue)));
586                 free(fieldNames[i]);
587                 free(fieldValue);
588         }
589         free(fieldNames);
590
591         DownloadRequest *request = new DownloadRequest();
592
593         if (url) {
594                 request->setUrl(url);
595                 free(url);
596         }
597
598         if (destination) {
599                 std::string virtualPath;
600                 try {
601                         virtualPath = DeviceAPI::Filesystem::Utils::toVirtualPath(NULL, destination);
602                 } catch (...) {
603                         LogWarning("Platform error while converting destination path.");
604                         virtualPath = destination;
605                 }
606                 request->setDestination(virtualPath);
607                 free(destination);
608         }
609
610         if (fileName) {
611                 request->setFileName(fileName);
612                 free(fileName);
613         }
614
615         switch(networkTypeValue) {
616         case DOWNLOAD_NETWORK_DATA_NETWORK:
617                 request->setNetworkType(TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_CELLULAR);
618                 break;
619         case DOWNLOAD_NETWORK_WIFI:
620                 request->setNetworkType(TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_WIFI);
621                 break;
622         default:
623                 request->setNetworkType(TIZEN_ENUM_DOWNLOAD_NETWORK_TYPE_ALL);
624                 break;
625         }
626
627         if (fieldLength) {
628                 request->setHttpHeader(httpHeader);
629         }
630
631
632         return request;
633 }
634
635 std::string DownloadManager::getMIMEType(long downloadId)
636 {
637         int ret;
638         char *mimeType = NULL;
639         std::string result("");
640
641         LogDebug("entered. downloadId = %d", downloadId);
642
643         ret = download_get_mime_type(downloadId, &mimeType);
644         if (ret != DOWNLOAD_ERROR_NONE) {
645                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
646                         throw NotFoundException("download id could not found.");
647                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
648                         throw InvalidValuesException("download id is not valid.");
649                 } else if (ret == DOWNLOAD_ERROR_NO_DATA) {
650                         result = "";
651                 } else {
652                         throw UnknownException(("Platform error while getting MIME type. " + _get_download_error(ret)).c_str()); 
653                 }
654         } else {
655                 result = mimeType;
656         }
657
658         if (mimeType) {
659                 free(mimeType);
660         }
661
662         return result;
663 }
664
665 void DownloadManager::setListener(long downloadId, DownloadCallback *downloadCallback)
666 {
667         int ret;
668
669         LogDebug("entered. downloadId = %d", downloadId);
670
671         ret = download_set_state_changed_cb(downloadId, download_state_changed_cb, this);
672         if (ret != DOWNLOAD_ERROR_NONE) {
673                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
674                         throw NotFoundException("download id could not found.");
675                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
676                         throw InvalidValuesException("download id is not valid.");
677                 }
678                 throw UnknownException(("Platform error while setting state changed callback. " + _get_download_error(ret)).c_str());
679         }
680
681         ret = download_set_progress_cb(downloadId, download_progress_cb, this);
682         if (ret != DOWNLOAD_ERROR_NONE) {
683                 if (ret == DOWNLOAD_ERROR_ID_NOT_FOUND) {
684                         throw NotFoundException("download id could not found.");
685                 } else if (ret == DOWNLOAD_ERROR_INVALID_PARAMETER) {
686                         throw InvalidValuesException("download id is not valid.");
687                 }
688                 throw UnknownException(("Platform error while setting progress callback. " + _get_download_error(ret)).c_str());
689         }
690
691         setCallbackToMap(downloadId, downloadCallback);
692 }
693
694 } // Download
695 } // DeviceAPI