2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file FCnt_DownloadManagerImpl.cpp
19 * @brief This is the implementation file for the _DownloadManagerImpl class.
27 #include <unique_ptr.h>
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>
38 #include <FCntDownloadRequest.h>
39 #include <FCntIDownloadListener.h>
41 #include <FCnt_DownloadRequestImpl.h>
42 #include "FCnt_DownloadManagerImpl.h"
46 using namespace Tizen::Base;
47 using namespace Tizen::Base::Runtime;
48 using namespace Tizen::Base::Collection;
50 namespace Tizen { namespace Content
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;
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;
71 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
73 _DownloadManagerImpl* _DownloadManagerImpl::__pInstance = null;
75 class _DownloadEventArg
92 unsigned long long __received;
93 unsigned long long __total;
100 virtual void FireImpl(IEventListener& listener, const IEventArg& arg)
102 IDownloadListener* pListener = dynamic_cast<IDownloadListener*> (&listener);
103 if (pListener != null)
105 const _DownloadEventArg* pArg = dynamic_cast<const _DownloadEventArg*>(&arg);
108 switch(pArg->__state)
114 case STATE_DOWNLOADING:
115 pListener->OnDownloadInProgress(pArg->__id, pArg->__received, pArg->__total);
119 pListener->OnDownloadPaused(pArg->__id);
122 case STATE_COMPLETED:
123 pListener->OnDownloadCompleted(pArg->__id, pArg->__path);
127 pListener->OnDownloadFailed(pArg->__id, pArg->__result, pArg->__errorCode);
130 case STATE_CANCELLED:
131 pListener->OnDownloadCanceled(pArg->__id);
144 OnStateChanged(int download_id, download_state_e state, void* data)
146 SysLog(NID_CNT, "OnStateChanged, id = %d, state = %d", download_id, state);
148 RequestId reqId = (long)download_id;
150 _DownloadManagerImpl* pDMImpl = (_DownloadManagerImpl*)data;
160 case SLP_STATE_QUEUED:
161 case SLP_STATE_DOWNLOADING:
164 case SLP_STATE_PAUSED:
166 pthread_mutex_lock(&mutex);
167 if (pDMImpl->__pEvent)
169 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
170 pEventArg->__id = reqId;
171 pEventArg->__state = STATE_PAUSED;
173 pDMImpl->__pEvent->Fire(*pEventArg);
175 pthread_mutex_unlock(&mutex);
180 case SLP_STATE_COMPLETED:
182 pthread_mutex_lock(&mutex);
183 if (pDMImpl->__pEvent)
185 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
186 pEventArg->__id = reqId;
187 pEventArg->__state = STATE_COMPLETED;
190 download_get_downloaded_file_path(download_id, &path);
191 pEventArg->__path = path;
195 pDMImpl->__pEvent->Fire(*pEventArg);
197 pthread_mutex_unlock(&mutex);
199 // Remove the resource from url_download
200 pDMImpl->DestroyResources(reqId);
205 case SLP_STATE_FAILED:
207 pthread_mutex_lock(&mutex);
208 if (pDMImpl->__pEvent)
210 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
211 pEventArg->__id = reqId;
212 pEventArg->__state = STATE_FAILED;
214 download_error_e error;
215 download_get_error(download_id, &error);
216 pEventArg->__result = pDMImpl->ConvertToResult(error);
219 download_get_http_status(download_id, &http_status);
220 pEventArg->__errorCode = Integer::ToString(http_status);
222 pDMImpl->__pEvent->Fire(*pEventArg);
224 pthread_mutex_unlock(&mutex);
226 // Comment out due to resume the failed request
227 //pDMImpl->DestroyResources(reqId);
232 case SLP_STATE_CANCELLED:
234 pthread_mutex_lock(&mutex);
235 if (pDMImpl->__pEvent)
237 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
238 pEventArg->__id = reqId;
239 pEventArg->__state = STATE_CANCELLED;
241 pDMImpl->__pEvent->Fire(*pEventArg);
243 pthread_mutex_unlock(&mutex);
245 // Remove the resource from url_download
246 pDMImpl->DestroyResources(reqId);
258 OnProgress(int download_id, unsigned long long received, void* data)
260 RequestId reqId = (long)download_id;
262 _DownloadManagerImpl* pDMImpl = (_DownloadManagerImpl*)data;
264 pthread_mutex_lock(&mutex);
265 if (data && pDMImpl->__pEvent)
267 _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
268 pEventArg->__id = reqId;
269 pEventArg->__state = STATE_DOWNLOADING;
270 pEventArg->__received = received;
272 unsigned long long total = 0;
273 download_get_content_size(download_id, &total);
274 pEventArg->__total = total;
276 SysLog(NID_CNT, "OnProgress, id = %d, received = %lld, total = %lld", download_id, received, total);
278 pDMImpl->__pEvent->Fire(*pEventArg);
280 pthread_mutex_unlock(&mutex);
284 _DownloadManagerImpl::_DownloadManagerImpl(void)
289 _DownloadManagerImpl::~_DownloadManagerImpl(void)
298 _DownloadManagerImpl::InitSingleton(void)
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.");
303 __pInstance = pImpl.release();
305 std::atexit(DestroySingleton);
309 _DownloadManagerImpl::DestroySingleton(void)
314 _DownloadManagerImpl*
315 _DownloadManagerImpl::GetInstance(void)
317 static pthread_once_t onceBlock = PTHREAD_ONCE_INIT;
318 if (__pInstance == null)
322 pthread_once(&onceBlock, InitSingleton);
323 result r = GetLastResult();
326 onceBlock = PTHREAD_ONCE_INIT;
334 _DownloadManagerImpl::Start(const DownloadRequest& request, RequestId& reqId)
336 SysLog(NID_CNT, "Start a download from Url = %ls, Path = %ls", request.GetUrl().GetPointer(), request.GetDirectoryPath().GetPointer());
338 result r = E_SUCCESS;
343 String url = request.GetUrl();
344 String dirPath = request.GetDirectoryPath();
345 String fileName = request.GetFileName();
346 NetworkType networkType = (NetworkType)request.GetNetworkType();
348 SysTryReturnResult(NID_CNT, !url.IsEmpty(), E_INVALID_ARG, "The url of the download request is empty.");
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);
355 unique_ptr<char[]> pUrl(_StringConverter::CopyToCharArrayN(url));
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);
361 if (networkType == NETWORK_ALL)
363 ret = download_set_network_type(download_id, (download_network_type_e)DOWNLOAD_NETWORK_ALL);
367 ret = download_set_network_type(download_id, (download_network_type_e)networkType);
369 SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
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);
375 //Set notification extra data
376 std::unique_ptr<IMapEnumerator> pMapEnum(const_cast< IMap* >(request.GetNotificationExtraData())->GetMapEnumeratorN());
378 while (pMapEnum->MoveNext() == E_SUCCESS)
380 String* pMapKey = dynamic_cast<String*>(pMapEnum->GetKey());
381 String* pMapValue = dynamic_cast<String*>(pMapEnum->GetValue());
383 if (pMapKey && pMapValue)
385 unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(*pMapKey));
386 const char* pValue = _StringConverter::CopyToCharArrayN(*pMapValue);
388 ret = download_add_notification_extra_param(download_id, pKey.get(), &pValue, 1);
390 SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
395 IMap* pRequestHeader = _DownloadRequestImpl::GetInstance(&request)->GetRequestHeader();
396 std::unique_ptr<IMapEnumerator> pMapEnume(const_cast< IMap* >(pRequestHeader)->GetMapEnumeratorN());
397 while (pMapEnume->MoveNext() == E_SUCCESS)
399 String* pMapKey = dynamic_cast<String*>(pMapEnume->GetKey());
400 String* pMapValue = dynamic_cast<String*>(pMapEnume->GetValue());
401 if (pMapKey && pMapValue)
403 unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(*pMapKey));
404 unique_ptr<char[]> pValue(_StringConverter::CopyToCharArrayN(*pMapValue));
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);
412 // Check the download path
413 if (!dirPath.IsEmpty())
415 unique_ptr<char[]> pStr(_StringConverter::CopyToCharArrayN(dirPath));
417 ret = access(pStr.get(), F_OK);
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.");
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);
429 if (!fileName.IsEmpty())
431 unique_ptr<char[]> pStr(_StringConverter::CopyToCharArrayN(fileName));
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);
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);
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);
447 reqId = (long)download_id;
452 UnregisterCallback((long)download_id);
458 _DownloadManagerImpl::Pause(RequestId reqId)
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);
473 _DownloadManagerImpl::Resume(RequestId reqId)
476 result r = E_SUCCESS;
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);
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);
494 UnregisterCallback((int)reqId);
500 _DownloadManagerImpl::Cancel(RequestId reqId)
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);
514 _DownloadManagerImpl::GetDownloadRequestN(RequestId reqId)
516 result r = E_SUCCESS;
517 DownloadRequest* pRequest = null;
521 bool notification = false;
523 char** pFields = null;
525 char* pFileName = null;
526 download_network_type_e netType = (download_network_type_e)DOWNLOAD_NETWORK_DATA_NETWORK;
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, ¬ification);
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++)
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);
565 _DownloadManagerImpl::GetMimeType(RequestId reqId, String& mimeType)
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);
582 _DownloadManagerImpl::GetState(RequestId reqId) const
586 download_state_e download_state = (download_state_e)SLP_STATE_NONE;
587 int state = STATE_NONE;
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);
593 switch(download_state)
599 case SLP_STATE_READY:
600 state = STATE_QUEUED;
603 case SLP_STATE_QUEUED:
604 state = STATE_QUEUED;
607 case SLP_STATE_DOWNLOADING:
608 state = STATE_DOWNLOADING;
611 case SLP_STATE_PAUSED:
612 state = STATE_PAUSED;
615 case SLP_STATE_COMPLETED:
616 state = STATE_COMPLETED;
619 case SLP_STATE_CANCELLED:
620 state = STATE_CANCELLED;
623 case SLP_STATE_FAILED:
624 state = STATE_FAILED;
632 SysLog(NID_CNT, "download_state = %d, state = %d", download_state, state);
638 _DownloadManagerImpl::GetProgress(RequestId reqId, int& progress)
644 _DownloadManagerImpl::SetAllowedNetwork(unsigned long flags)
650 _DownloadManagerImpl::SetDownloadListener(IDownloadListener* pListener)
652 pthread_mutex_lock(&mutex);
654 if (pListener != null)
656 _DownloadEvent* pEvent = new (std::nothrow) _DownloadEvent();
657 SysTryReturnVoidResult(NID_IO, pEvent != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
659 pEvent->AddListener(*pListener);
665 if (__pEvent != null)
673 pthread_mutex_unlock(&mutex);
677 _DownloadManagerImpl::DestroyResources(RequestId reqId)
681 // Cancel the callback
682 UnregisterCallback(reqId);
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);
690 _DownloadManagerImpl::RegisterCallback(RequestId reqId)
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);
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);
700 return DOWNLOAD_ERROR_NONE;
703 UnregisterCallback(reqId);
709 _DownloadManagerImpl::UnregisterCallback(RequestId reqId)
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);
716 ret = download_unset_progress_cb(reqId);
717 SysTryLog(NID_CNT, ret >= 0, "download_unset_progress_cb fails %d, id = %d", ret, reqId);
721 _DownloadManagerImpl::ConvertToResult(int error)
723 result r = E_SUCCESS;
724 download_error_e download_error = (download_error_e)error;
726 SysLog(NID_CNT, "Download error = %d", download_error);
728 switch(download_error)
730 case DOWNLOAD_ERROR_NONE:
734 case DOWNLOAD_ERROR_OUT_OF_MEMORY:
738 case DOWNLOAD_ERROR_IO_ERROR:
742 case DOWNLOAD_ERROR_INVALID_URL:
746 case DOWNLOAD_ERROR_ID_NOT_FOUND:
750 case DOWNLOAD_ERROR_CONNECTION_FAILED:
751 case DOWNLOAD_ERROR_NETWORK_UNREACHABLE:
752 r = E_CONNECTION_FAILED;
755 case DOWNLOAD_ERROR_CONNECTION_TIMED_OUT:
759 case DOWNLOAD_ERROR_TOO_MANY_DOWNLOADS:
763 case DOWNLOAD_ERROR_NO_SPACE:
767 case DOWNLOAD_ERROR_QUEUE_FULL:
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:
780 } } // Tizen::Content