3209d32a75e848e67fc4c4f5764eb9e6a636ff2e
[platform/framework/native/content.git] / src / FCnt_ContentDownloadHandler.cpp
1 //
2 // Open Service Platform
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  * @file                FCnt_ContentDownloadHandler.cpp
19  * @brief               This is the implementation file for the %_ContentDownloadHandler class.
20  *
21  * This file contains implementation of the %_ContentDownloadHandler class.
22  */
23
24 #include <FBaseSysLog.h>
25 #include <FCnt_ContentManagerImpl.h>
26 #include <FCnt_ContentTransferImpl.h>
27 #include <FIo_FileImpl.h>
28 #include <FNetHttp_HttpSessionImpl.h>
29 #include <FNetHttp_HttpTransactionImpl.h>
30 #include <FSys_RuntimeInfoImpl.h>
31 #include "FCnt_ContentDownloadHandler.h"
32
33 using namespace Tizen;
34 using namespace Tizen::Base;
35 using namespace Tizen::Base::Utility;
36 using namespace Tizen::Io;
37 using namespace Tizen::Net;
38 using namespace Tizen::Net::Http;
39 using namespace Tizen::System;
40
41 static RequestId restRequestId = 0;
42
43 namespace Tizen { namespace Content
44 {
45
46 _ContentDownloadHandler::_ContentDownloadHandler(void)
47         : __requestId(INVALID_REQUEST_ID)
48         , __restRequestId(INVALID_REQUEST_ID)
49         , __timeout(-1)
50         , __percent(-1)
51         , __slot(-1)
52         , __destFilePath(L"")
53         , __sourceFilePath(L"")
54         , __pListener(null)
55         , __pSession(null)
56         , __pTransaction(null)
57 {
58 }
59
60 result
61 _ContentDownloadHandler::Construct(void)
62 {
63         ClearLastResult();
64         result r = E_SUCCESS;
65
66         std::unique_ptr<_ContentDownloadListener> pListener(new (std::nothrow) _ContentDownloadListener);
67         SysTryReturn(NID_CNT, pListener != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
68                            "[E_OUT_OF_MEMORY] Failed to construct ContentDownloadListener.");
69
70         __pListener = std::move(pListener);
71
72         return r;
73 }
74
75 _ContentDownloadHandler::~_ContentDownloadHandler(void)
76 {
77
78 }
79
80 result
81 _ContentDownloadHandler::Cancel(RequestId requestId, _ContentDownloadUserData* pContentDownloadUserDataSequence)
82 {
83         SysLog(NID_CNT, "Cancel operation start with request ID(%d).", requestId);
84         ClearLastResult();
85         result r = E_SUCCESS;
86
87         _HttpSessionImpl* pSessionImpl = null;
88         HttpResponse* pHttpResponse = null;
89         String errorMsg(L"");
90         int statusCode = -1;
91
92         SysTryReturn(NID_CNT, pContentDownloadUserDataSequence != null, r = E_INVALID_ARG, r,
93                         "[E_INVALID_ARG] ContentDownloadUserData instance must not be null.");
94         SysTryReturn(NID_CNT, __pSession != null, r = E_OBJ_NOT_FOUND, r, "[E_OBJ_NOT_FOUND] HttpSession instance must not be null.");
95         SysTryReturn(NID_CNT, __pTransaction != null, r = E_OBJ_NOT_FOUND, r, "[E_OBJ_NOT_FOUND] HttpTransaction instance must not be null.");
96
97
98         pSessionImpl = _HttpSessionImpl::GetInstance(*(__pSession.get()));
99         SysTryReturn(NID_CNT, pSessionImpl != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
100                            "[E_OUT_OF_MEMORY] Failed to create the HTTP session impl object.");
101
102         pHttpResponse = __pTransaction->GetResponse();
103         r = GetLastResult();
104         if (IsFailed(r))
105         {
106                 SysTryLog(NID_CNT, pHttpResponse != null, "[%s] Failed to get the Http transaction response.", GetErrorMessage(r));
107         }
108         else
109         {
110                 statusCode = pHttpResponse->GetHttpStatusCode();
111                 SysTryReturn(NID_CNT, statusCode == HTTP_STATUS_OK, r = E_SERVICE_UNAVAILABLE, E_SERVICE_UNAVAILABLE,
112                                            "[E_SERVICE_UNAVAILABLE] The server is unavailable.");
113
114                 errorMsg = pHttpResponse->GetStatusText();
115                 r = GetLastResult();
116                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_SERVICE_UNAVAILABLE, E_SERVICE_UNAVAILABLE,
117                                 "[E_SERVICE_UNAVAILABLE] The server is unavailable.");
118         }
119
120         if (__restRequestId == requestId)
121         {
122                 r = pSessionImpl->CancelTransaction(*__pTransaction);
123                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to cancel transaction.", GetErrorMessage(r));
124
125                 __requestId = INVALID_REQUEST_ID;
126         }
127         else
128         {
129                 SysTryReturn(NID_CNT, __restRequestId == requestId, r = E_INVALID_STATE, E_INVALID_STATE,
130                                 "[E_INVALID_STATE] Failed to find request ID.");
131         }
132
133         // delete downloaded file
134         if (_FileImpl::IsFileExist(pContentDownloadUserDataSequence->GetDestPath()))
135         {
136                 r = _FileImpl::Remove(pContentDownloadUserDataSequence->GetDestPath());
137                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to remove the [%ls] file.",
138                                 GetErrorMessage(r), (pContentDownloadUserDataSequence->GetDestPath()).GetPointer());
139         }
140
141         __pListener->DownloadCanceled(pContentDownloadUserDataSequence, statusCode, errorMsg, E_SUCCESS);
142
143         return r;
144 }
145
146 RequestId
147 _ContentDownloadHandler::HttpDownload(const String uri, int srcFileSize, const String destPath,
148                                                                           _ContentDownloadUserData* pContentDownloadUserDataSequence)
149 {
150         ClearLastResult();
151         result r = E_SUCCESS;
152
153         bool check = false;
154
155         SysTryReturn(NID_CNT, pContentDownloadUserDataSequence != null, __restRequestId, E_INVALID_ARG,
156                         "[E_INVALID_ARG] ContentDownloadUserData instance must not be null.");
157
158         check = CheckSystem(destPath, srcFileSize);
159         r = GetLastResult();
160         SysTryReturn(NID_CNT, check == true, __restRequestId, r, "[%s] The result of system check is false.", GetErrorMessage(r));
161
162         __sourceFilePath = uri;
163         SysTryReturn(NID_CNT, !__sourceFilePath.IsEmpty(), __restRequestId, E_INVALID_ARG,
164                         "[E_INVALID_ARG] The source URI is empty.");
165
166         pContentDownloadUserDataSequence->SetUrl(__sourceFilePath);
167         SysTryReturn(NID_CNT, !(pContentDownloadUserDataSequence->GetUrl().IsEmpty()), __restRequestId, E_INVALID_ARG,
168                            "[E_INVALID_ARG] Failed to set the source file path into ContentDownloadUserData.");
169
170         r = RequestDownload(__sourceFilePath, destPath, __timeout, __percent, pContentDownloadUserDataSequence);
171         SysTryReturn(NID_CNT, !IsFailed(r), __restRequestId, E_SYSTEM, "[E_SYSTEM] Failed to perform RequestDownload operation.");
172
173         return __restRequestId;
174 }
175
176 result
177 _ContentDownloadHandler::RequestDownload(String& srcUrl, const String destFilePath, int timeout,
178                                                                         int percent, _ContentDownloadUserData* pUserData)
179 {
180         SysLog(NID_CNT, "Download request operation start with URL(%ls) and destination path(%ls).", srcUrl.GetPointer(), destFilePath.GetPointer());
181
182         ClearLastResult();
183         result r = E_SUCCESS;
184         _HttpSessionImpl* pSessionImpl = null;
185         _HttpTransactionImpl* pTransactionImpl = null;
186         HttpRequest* pHttpRequest = null;
187         Uri uri;
188         String hostAddr(L"");
189
190         SysTryReturn(NID_CNT, pUserData != null, r = E_INVALID_ARG, E_INVALID_ARG,
191                         "[E_INVALID_ARG] ContentDownloadUserData instance must not be null.");
192
193         r = uri.SetUri(srcUrl);
194         SysTryReturn(NID_CNT, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] [%ls] is an invalid URL.", srcUrl.GetPointer());
195
196         hostAddr = uri.GetHost();
197
198         // Create HTTP session
199         __pSession = std::unique_ptr<HttpSession>(new (std::nothrow) HttpSession);
200         SysTryReturn(NID_CNT, __pSession != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
201                            "[E_OUT_OF_MEMORY] Failed to create the HTTP session.");
202
203         r = __pSession->Construct(NET_HTTP_SESSION_MODE_NORMAL, null, hostAddr, null);
204         SysTryReturn(NID_CNT, r == E_SUCCESS, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to construct HTTP session.");
205
206         pSessionImpl = _HttpSessionImpl::GetInstance(*(__pSession.get()));
207         SysTryReturn(NID_CNT, pSessionImpl != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
208                            "[E_OUT_OF_MEMORY] Failed to create the HTTP session impl object.");
209
210         __pTransaction = std::unique_ptr<HttpTransaction>(pSessionImpl->OpenTransactionN());
211         SysTryReturn(NID_CNT, __pTransaction != null, r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to create the HTTP transaction.");
212
213         pTransactionImpl = _HttpTransactionImpl::GetInstance(*(__pTransaction.get()));
214         SysTryReturn(NID_CNT, pTransactionImpl != null, r = E_SYSTEM, E_SYSTEM,
215                            "[E_SYSTEM] Failed to get HTTP transaction impl object.");
216
217         r = pTransactionImpl->SetTimeout(timeout);
218         SysTryReturn(NID_CNT, r == E_SUCCESS, r, r, "[%s] Failed to set [%d] timeout.", GetErrorMessage(r), timeout);
219
220         r = pTransactionImpl->AddHttpTransactionListener(*(__pListener.get()));
221         SysTryReturn(NID_CNT, r == E_SUCCESS, r, r, "[%s] Failed to add listener into the HTTP transaction.", GetErrorMessage(r));
222
223         r = pTransactionImpl->SetHttpProgressListener(*(__pListener.get()));
224         SysTryReturn(NID_CNT, r == E_SUCCESS, r, r, "[%s] Failed to add listener into the HTTP transaction.", GetErrorMessage(r));
225
226         __destFilePath = destFilePath;
227         pUserData->SetDestPath(__destFilePath);
228         SysTryReturn(NID_CNT, !(pUserData->GetDestPath().IsEmpty()), r = E_INVALID_ARG, E_INVALID_ARG,
229                            "[E_INVALID_ARG] Failed to set the destination path [%ls] into user data.", __destFilePath.GetPointer());
230
231         pHttpRequest = pTransactionImpl->GetRequest();
232         r = pHttpRequest->SetUri(srcUrl);
233         SysTryReturn(NID_CNT, r == E_SUCCESS, r, r, "[%s] Failed to set uri into the HTTP request.", GetErrorMessage(r));
234
235         r = pHttpRequest->SetMethod(NET_HTTP_METHOD_GET);
236         SysTryReturn(NID_CNT, r == E_SUCCESS, r, r, "[%s] Failed to set method into the HTTP request.", GetErrorMessage(r));
237
238         r = pTransactionImpl->SetUserObject(pUserData);
239         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to set UserData for the HTTP transaction.", GetErrorMessage(r));
240
241         r = pTransactionImpl->Submit();
242         SysTryReturn(NID_CNT, r == E_SUCCESS, r, r, "[%s] Failed to submit the HTTP request.", GetErrorMessage(r));
243
244         ++restRequestId;
245         __restRequestId = restRequestId;
246
247         return r;
248 }
249
250 bool
251 _ContentDownloadHandler::CheckSystem(const String& destPath, int srcFileSize)
252 {
253         ClearLastResult();
254         result r = E_SUCCESS;
255         String key(L"AvailableMediaStorage");
256         long long availableSize = 0;
257         long long fileSize = 0;
258         fileSize = static_cast<long long>(srcFileSize);
259
260         // if existed duplicated file
261         if (_FileImpl::IsFileExist(destPath))
262         {
263                 r = _FileImpl::Remove(destPath);
264                 SysTryReturn(NID_CNT, !IsFailed(r), false, r,
265                                 "[%s] Failed to remove the duplicated file [%ls].", GetErrorMessage(r), destPath.GetPointer());
266         }
267
268         r = _RuntimeInfoImpl::GetValue(key, availableSize);
269         SysTryReturn(NID_CNT, !IsFailed(r), false, r, "[%s] Failed to get the available size.", GetErrorMessage(r));
270
271         if (fileSize > availableSize)
272         {
273                 SysLogException(NID_CNT, E_INVALID_STATE, "[E_INVALID_STATE] File size exceeds the available disk quota.");
274                 return false;
275         }
276
277         return true;
278 }
279
280 void
281 _ContentDownloadHandler::SetTimeout(int sec)
282 {
283         this->__timeout = sec;
284 }
285
286 void
287 _ContentDownloadHandler::SetProgressIntervalByPercent(int percent)
288 {
289         this->__percent = percent;
290 }
291
292 void
293 _ContentDownloadHandler::SetDownloadPath(String destFilePath)
294 {
295         this->__destFilePath = destFilePath;
296 }
297
298 void
299 _ContentDownloadHandler::SetSlot(int slot)
300 {
301         this->__slot = slot;
302 }
303
304 void
305 _ContentDownloadHandler::SetRequestId(RequestId requestId)
306 {
307         this->__requestId = requestId;
308 }
309
310 }}