#include <FBaseSysLog.h>
#include <FBase_StringConverter.h>
+#include <FBaseInteger.h>
+#include <FBaseRtIEventArg.h>
#include <FBaseColIMap.h>
#include <FApp_AppInfo.h>
#include <FCntDownloadRequest.h>
#include <FCntIDownloadListener.h>
+#include <FCnt_DownloadRequestImpl.h>
#include "FCnt_DownloadManagerImpl.h"
using namespace std;
using namespace Tizen::Base;
+using namespace Tizen::Base::Runtime;
using namespace Tizen::Base::Collection;
namespace Tizen { namespace Content
_DownloadManagerImpl* _DownloadManagerImpl::__pInstance = null;
+class _DownloadEventArg
+ : public IEventArg
+{
+public:
+ _DownloadEventArg()
+ : __id(-1)
+ , __state((download_state_e)DOWNLOAD_STATE_NONE)
+ , __result(-1)
+ , __received(-1)
+ , __total(-1)
+ {
+ }
+ RequestId __id;
+ download_state_e __state;
+ String __path;
+ result __result;
+ String __errorCode;
+ unsigned long long __received;
+ unsigned long long __total;
+};
+
+class _DownloadEvent
+ : public Event
+{
+protected:
+ virtual void FireImpl(IEventListener& listener, const IEventArg& arg)
+ {
+ IDownloadListener* pListener = dynamic_cast<IDownloadListener*> (&listener);
+ if (pListener != null)
+ {
+ const _DownloadEventArg* pArg = dynamic_cast<const _DownloadEventArg*>(&arg);
+ if (pArg != null)
+ {
+ switch(pArg->__state)
+ {
+ case DOWNLOAD_STATE_NONE:
+ case DOWNLOAD_STATE_QUEUED:
+ break;
+
+ case DOWNLOAD_STATE_DOWNLOADING:
+ pListener->OnDownloadInProgress(pArg->__id, pArg->__received, pArg->__total);
+ break;
+
+ case DOWNLOAD_STATE_PAUSED:
+ pListener->OnDownloadPaused(pArg->__id);
+ break;
+
+ case DOWNLOAD_STATE_COMPLETED:
+ pListener->OnDownloadCompleted(pArg->__id, pArg->__path);
+ break;
+
+ case DOWNLOAD_STATE_FAILED:
+ pListener->OnDownloadFailed(pArg->__id, pArg->__result, pArg->__errorCode);
+ break;
+
+ case DOWNLOAD_STATE_CANCELED:
+ pListener->OnDownloadCanceled(pArg->__id);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+};
+
static void
OnStateChanged(int download_id, download_state_e state, void* data)
{
_DownloadManagerImpl* pDMImpl = (_DownloadManagerImpl*)data;
- if (!data || !pDMImpl->__pListener)
+ if (!data || !pDMImpl->__pEvent)
{
return;
}
break;
case DOWNLOAD_STATE_PAUSED:
- pDMImpl->__pListener->OnDownloadPaused(reqId);
- break;
+ {
+ _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
+ pEventArg->__id = reqId;
+ pEventArg->__state = state;
+
+ pDMImpl->__pEvent->Fire(*pEventArg);
+ break;
+ }
case DOWNLOAD_STATE_COMPLETED:
{
+ _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
+ pEventArg->__id = reqId;
+ pEventArg->__state = state;
+
char* path = null;
download_get_downloaded_file_path(download_id, &path);
- pDMImpl->__pListener->OnDownloadCompleted(reqId, path);
+ pEventArg->__path = path;
delete[] path;
+ pDMImpl->__pEvent->Fire(*pEventArg);
+
// Remove the resource from url_download
pDMImpl->DestroyResources(reqId);
+
break;
}
case DOWNLOAD_STATE_FAILED:
{
- result r = E_SUCCESS;
- download_error_e error;
- int http_status = 0;
+ _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
+ pEventArg->__id = reqId;
+ pEventArg->__state = state;
+ download_error_e error;
download_get_error(download_id, &error);
+ pEventArg->__result = pDMImpl->ConvertToResult(error);
+
+ int http_status = 0;
download_get_http_status(download_id, &http_status);
- r = pDMImpl->ConvertToResult(error);
+ pEventArg->__errorCode = Integer::ToString(http_status);
- String errorCode;
- pDMImpl->__pListener->OnDownloadFailed(reqId, r, http_status);
+ pDMImpl->__pEvent->Fire(*pEventArg);
// Comment out due to resume the failed request
//pDMImpl->DestroyResources(reqId);
+
break;
}
case DOWNLOAD_STATE_CANCELED:
- pDMImpl->__pListener->OnDownloadCanceled(reqId);
+ {
+ _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
+ pEventArg->__id = reqId;
+ pEventArg->__state = state;
+
+ pDMImpl->__pEvent->Fire(*pEventArg);
// Remove the resource from url_download
pDMImpl->DestroyResources(reqId);
- break;
+ break;
+ }
default:
break;
}
_DownloadManagerImpl* pDMImpl = (_DownloadManagerImpl*)data;
- if (data && pDMImpl->__pListener)
+ if (data && pDMImpl->__pEvent)
{
+ _DownloadEventArg* pEventArg = new (std::nothrow) _DownloadEventArg();
+ pEventArg->__id = reqId;
+ pEventArg->__state = (download_state_e)DOWNLOAD_STATE_DOWNLOADING;
+ pEventArg->__received = received;
+
unsigned long long total = 0;
download_get_content_size(download_id, &total);
+ pEventArg->__total = total;
SysLog(NID_CNT, "OnProgress, id = %d, received = %lld, total = %lld", download_id, received, total);
- pDMImpl->__pListener->OnDownloadInProgress(reqId, received, total);
+ pDMImpl->__pEvent->Fire(*pEventArg);
}
}
_DownloadManagerImpl::_DownloadManagerImpl(void)
- : __pListener(null)
+ : __pEvent(null)
{
}
_DownloadManagerImpl::~_DownloadManagerImpl(void)
{
+ if (__pEvent)
+ {
+ delete __pEvent;
+ }
}
result
result r = E_SUCCESS;
r = __handleMap.Construct(100, 0);
+ SysTryReturnResult(NID_IO, r == E_SUCCESS, r, "Failed to initialize a download manager.");
- return r;
+ return E_SUCCESS;
}
void
String url = request.GetUrl();
String dirPath = request.GetDirectoryPath();
String fileName = request.GetFileName();
+ NetworkType networkType = (NetworkType)request.GetNetworkType();
SysTryReturnResult(NID_CNT, !url.IsEmpty(), E_INVALID_ARG, "The url of the download request is empty.");
// Create a download id
ret = download_create(&download_id);
- SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available.");
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
// Set the url
unique_ptr<char[]> pUrl(_StringConverter::CopyToCharArrayN(url));
ret = download_set_url(download_id, pUrl.get());
- SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available.");
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
+
+ //Set network type
+ if (networkType == NETWORK_ALL)
+ {
+ ret = download_set_network_type(download_id, (download_network_type_e)DOWNLOAD_NETWORK_ALL);
+ }
+ else
+ {
+ ret = download_set_network_type(download_id, (download_network_type_e)networkType);
+ }
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
+
+ //Set notification
+ ret = download_set_notification(download_id, request.IsNotificationEnabled());
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
+
+ //Set notification extra data
+ std::unique_ptr<IMapEnumerator> pMapEnum(const_cast< IMap* >(request.GetNotificationExtraData())->GetMapEnumeratorN());
+ while (pMapEnum->MoveNext() == E_SUCCESS)
+ {
+ String* pMapKey = dynamic_cast<String*>(pMapEnum->GetKey());
+ unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(*pMapKey));
+ String* pMapValue = dynamic_cast<String*>(pMapEnum->GetValue());
+ const char* pValue = _StringConverter::CopyToCharArrayN(*pMapValue);
+
+ ret = download_add_notification_extra_param(download_id, pKey.get(), &pValue, 1);
+ delete[] pValue;
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
+ }
+
+ //Add http headers
+ IMap* pRequestHeader = _DownloadRequestImpl::GetInstance(&request)->GetRequestHeader();
+ std::unique_ptr<IMapEnumerator> pMapEnume(const_cast< IMap* >(pRequestHeader)->GetMapEnumeratorN());
+ while (pMapEnume->MoveNext() == E_SUCCESS)
+ {
+ String* pMapKey = dynamic_cast<String*>(pMapEnume->GetKey());
+ unique_ptr<char[]> pKey(_StringConverter::CopyToCharArrayN(*pMapKey));
+ String* pMapValue = dynamic_cast<String*>(pMapEnume->GetValue());
+ unique_ptr<char[]> pValue(_StringConverter::CopyToCharArrayN(*pMapValue));
+
+ ret = download_add_http_header_field(download_id, pKey.get(), pValue.get());
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
+ }
// Check the download path
if (!dirPath.IsEmpty())
}
ret = download_set_destination(download_id, pStr.get());
- SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available.");
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
}
// Set the file name
unique_ptr<char[]> pStr(_StringConverter::CopyToCharArrayN(fileName));
ret = download_set_file_name(download_id, pStr.get());
- SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available.");
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
}
// Set the callback functions
// Start the download request
ret = download_start(download_id);
SysTryCatch(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_PARAMETER, r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The argument is not valid");
- SysTryCatch(NID_CNT, ret >= 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The internal system service is not available. error = %d", ret);
+ SysTryCatch(NID_CNT, ret >= 0, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] The internal system service is not available. %d", ret);
// Set a request Id
reqId = (long)download_id;
result r = E_SUCCESS;
int ret = 0;
- DownloadRequest* pRequest = null;
State state = STATE_NONE;
- // Check the request Id
- pRequest = GetDownloadRequestN(reqId);
- if(pRequest == null)
- {
- r = GetLastResult();
- SysPropagate(NID_CNT, r);
- return r;
- }
-
- delete pRequest;
-
// Get the current state
state = GetState(reqId);
+ SysTryReturnResult(NID_CNT, state != STATE_NONE, E_INVALID_ARG, "There is no download request for the request ID.");
// Check the pre-state
r = CheckPrestate(DOWNLOAD_OPERATION_PAUSE, state);
// Pause the download request
ret = download_pause((int)reqId);
- SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available.");
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
return E_SUCCESS;
}
result r = E_SUCCESS;
int ret = 0;
-
- DownloadRequest* pRequest = null;
State state = STATE_NONE;
- // Check the request Id
- pRequest = GetDownloadRequestN(reqId);
- if(pRequest == null)
- {
- r = GetLastResult();
- SysPropagate(NID_CNT, r);
- return r;
- }
- delete pRequest;
-
// Get the current state
state = GetState(reqId);
+ SysTryReturnResult(NID_CNT, state != STATE_NONE, E_INVALID_ARG, "There is no download request for the request ID.");
// Check the pre-state
r = CheckPrestate(DOWNLOAD_OPERATION_RESUME, state);
// Resume the download request
ret = download_start((int)reqId);
- SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available.");
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
return E_SUCCESS;
}
_DownloadManagerImpl::Cancel(RequestId reqId)
{
int ret = 0;
+ State state = STATE_NONE;
- DownloadRequest* pRequest = null;
-
- // Check the request Id
- pRequest = GetDownloadRequestN(reqId);
- if(pRequest == null)
- {
- result r = GetLastResult();
- SysPropagate(NID_CNT, r);
- return r;
- }
-
- delete pRequest;
+ // Get the current state
+ state = GetState(reqId);
+ SysTryReturnResult(NID_CNT, state != STATE_NONE, E_INVALID_ARG, "There is no download request for the request ID.");
// Stop the download request
ret = download_cancel((int)reqId);
- SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available.");
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
return E_SUCCESS;
}
DownloadRequest* pRequest = null;
r = __handleMap.GetValue(reqId, pRequest);
- SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_INVALID_ARG, "[E_INVALID_ARG] There is no download request for the request ID");
+ SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_INVALID_ARG, "[E_INVALID_ARG] There is no download request for the request ID.");
pRequest = new (std::nothrow) DownloadRequest(*pRequest);
SysTryReturn(NID_CNT, pRequest != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
ret = download_get_mime_type((int)reqId, &pStr);
SysTryReturnResult(NID_CNT, ret != DOWNLOAD_ERROR_INVALID_STATE, E_INVALID_OPERATION, "The current download state is not downloading or paused.");
- SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available.");
+ SysTryReturnResult(NID_CNT, ret >= 0, E_SYSTEM, "The internal system service is not available. %d", ret);
mimeType = pStr;
delete[] pStr;
{
int ret = 0;
- download_state_e download_state = DOWNLOAD_STATE_NONE;
+ download_state_e download_state = (download_state_e)DOWNLOAD_STATE_NONE;
State state = STATE_NONE;
ret = download_get_state((int)reqId, &download_state);
- SysTryReturn(NID_CNT, ret >= 0, STATE_NONE, E_SYSTEM, "[E_SYSTEM] The internal system service is not available.");
+ SysTryReturn(NID_CNT, ret != DOWNLOAD_ERROR_ID_NOT_FOUND, STATE_NONE, E_INVALID_ARG, "[E_INVALID_ARG] The request ID is not valid.");
+ SysTryReturn(NID_CNT, ret >= 0, STATE_NONE, E_SYSTEM, "[E_SYSTEM] The internal system service is not available. %d", ret);
switch(download_state)
{
state = STATE_NONE;
break;
- case DOWNLOAD_STATE_READY:
- state = STATE_QUEUED;
- break;
+ //case DOWNLOAD_STATE_READY:
+ // state = STATE_QUEUED;
+ // break;
case DOWNLOAD_STATE_QUEUED:
state = STATE_QUEUED;
break;
default:
- state = STATE_NONE;
+ //state = STATE_NONE;
+ state = STATE_QUEUED;
break;
}
void
_DownloadManagerImpl::SetDownloadListener(IDownloadListener* pListener)
{
- __pListener = pListener;
+ if (pListener != null)
+ {
+ _DownloadEvent* pEvent = new (std::nothrow) _DownloadEvent();
+ SysTryReturnVoidResult(NID_IO, pEvent != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
+
+ pEvent->AddListener(*pListener);
+
+ __pEvent = pEvent;
+ }
+ else
+ {
+ if (__pEvent != null)
+ {
+ delete __pEvent;
+ }
+
+ __pEvent = null;
+ }
}
result
break;
case DOWNLOAD_OPERATION_RESUME:
- // Check the pre-state: paused
+ // Check the pre-state: paused / failed
SysTryReturnResult(NID_CNT, !(current != STATE_PAUSED && current != STATE_FAILED), E_INVALID_OPERATION,
"The current download state is not STATE_PAUSED or STATE_FAILED.");
break;
case DOWNLOAD_OPERATION_CANCEL:
- // Check the pre-state: downloading
- //SysTryReturnResult(NID_CNT, current == STATE_DOWNLOADING, E_INVALID_OPERATION,
- //"The current download state prohibits the execution of this operation.");
break;
default:
r = E_INVALID_URL;
break;
+ case DOWNLOAD_ERROR_ID_NOT_FOUND:
+ r = E_INVALID_ARG;
+ break;
+
case DOWNLOAD_ERROR_CONNECTION_FAILED:
case DOWNLOAD_ERROR_NETWORK_UNREACHABLE:
r = E_CONNECTION_FAILED;