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