merge with master
[platform/framework/native/content.git] / src / FCnt_DownloadManagerImpl.cpp
index 4e9ade1..072fc6f 100644 (file)
 
 #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
@@ -49,6 +53,73 @@ 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)
 {
@@ -58,7 +129,7 @@ OnStateChanged(int download_id, download_state_e state, void* data)
 
        _DownloadManagerImpl* pDMImpl = (_DownloadManagerImpl*)data;
 
-       if (!data || !pDMImpl->__pListener)
+       if (!data || !pDMImpl->__pEvent)
        {
                return;
        }
@@ -71,47 +142,70 @@ OnStateChanged(int download_id, download_state_e state, void* data)
                        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;
        }
@@ -125,25 +219,35 @@ OnProgress(int download_id, unsigned long long received, void* data)
 
        _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
@@ -152,8 +256,9 @@ _DownloadManagerImpl::Construct(void)
        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
@@ -208,18 +313,62 @@ _DownloadManagerImpl::Start(const DownloadRequest& request, RequestId& reqId)
        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())
@@ -234,7 +383,7 @@ _DownloadManagerImpl::Start(const DownloadRequest& request, RequestId& reqId)
                }
 
                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
@@ -243,7 +392,7 @@ _DownloadManagerImpl::Start(const DownloadRequest& request, RequestId& reqId)
                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
@@ -253,7 +402,7 @@ _DownloadManagerImpl::Start(const DownloadRequest& request, RequestId& reqId)
        // 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;
@@ -275,22 +424,11 @@ _DownloadManagerImpl::Pause(RequestId reqId)
        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);
@@ -302,7 +440,7 @@ _DownloadManagerImpl::Pause(RequestId reqId)
 
        // 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;
 }
@@ -313,22 +451,11 @@ _DownloadManagerImpl::Resume(RequestId reqId)
        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);
@@ -340,7 +467,7 @@ _DownloadManagerImpl::Resume(RequestId reqId)
 
        // 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;
 }
@@ -349,23 +476,15 @@ result
 _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;
 }
@@ -377,7 +496,7 @@ _DownloadManagerImpl::GetDownloadRequestN(RequestId reqId)
        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]");
@@ -408,7 +527,7 @@ _DownloadManagerImpl::GetMimeType(RequestId reqId, String& mimeType)
 
        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;
@@ -421,11 +540,12 @@ _DownloadManagerImpl::GetState(RequestId reqId) const
 {
        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)
        {
@@ -433,9 +553,9 @@ _DownloadManagerImpl::GetState(RequestId reqId) const
                        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;
@@ -462,7 +582,8 @@ _DownloadManagerImpl::GetState(RequestId reqId) const
                        break;
 
                default:
-                       state = STATE_NONE;
+                       //state = STATE_NONE;
+                       state = STATE_QUEUED;
                        break;
        }
 
@@ -486,7 +607,24 @@ _DownloadManagerImpl::SetAllowedNetwork(unsigned long flags)
 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
@@ -503,15 +641,12 @@ _DownloadManagerImpl::CheckPrestate(DownloadOperation operation, State current)
                        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:
@@ -602,6 +737,10 @@ _DownloadManagerImpl::ConvertToResult(int error)
                        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;