Fix : The original content is restored again if CreateContent API fail
[platform/framework/native/content.git] / src / FCnt_ContentTransferImpl.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_ContentTransferImpl.cpp
18  * @brief               This is the implementation file for the %_ContentTransferImpl class.
19  *
20  * This file contains implementation of the %_ContentTransferImpl class.
21  */
22
23 #include <FBaseSysLog.h>
24 #include <FBaseString.h>
25 #include <FBaseColIList.h>
26 #include <FBaseUtilUri.h>
27 #include <FIoDirectory.h>
28 #include <FCntIContentTransferListener.h>
29 #include <FCntContentTransfer.h>
30 #include <FCntContentTransferInfo.h>
31 #include <FIoRegistry.h>
32 #include <FAppApp.h>
33 #include <FSysEnvironment.h>
34 #include <FApp_AppInfo.h>
35 #include <FCnt_ContentTransferImpl.h>
36 #include <FSys_EnvironmentImpl.h>
37 #include <FIo_FileImpl.h>
38 #include <FIo_FileAttributesImpl.h>
39 #include <FSys_SystemTimeImpl.h>
40 #include "FCnt_ContentDownloadHandler.h"
41 #include "FCnt_ContentTransferEvent.h"
42
43 using namespace Tizen;
44 using namespace Tizen::App;
45 using namespace Tizen::Base;
46 using namespace Tizen::Base::Collection;
47 using namespace Tizen::Base::Utility;
48 using namespace Tizen::Base::Runtime;
49 using namespace Tizen::Io;
50 using namespace Tizen::System;
51
52 static RequestId downloadRequestId = 0;
53 static bool initSlot = false;
54 static const int MAX_DOWNLOAD_COUNT = 5;
55
56 namespace Tizen { namespace Content
57 {
58
59 static const wchar_t CONTENT_DOWNLOAD_TEMP_DIRECTORY[] = L"/tmp/content_";
60 static const wchar_t CONTENT_DOWNLOAD_PATH_MEDIA[] = L"/Media";
61 static const wchar_t CONTENT_DOWNLOAD_PATH_MEDIA_MMC[] = L"/Storagecard/Media";
62 static const wchar_t CONTENT_DOWNLOAD_PATH_HOME[] = L"/Home";
63 static const wchar_t CONTENT_DOWNLOAD_PATH_HOME_MMC[] = L"/HomeExt";
64
65 static const int CONTENT_TRANSFER_DEFAULT_PROGRESS_INTERVAL = 0;
66 static const int CONTENT_DOWNLOAD_CHECKING_PERIOD = 1000;
67
68 _ContentTransferImpl::_ContentTransferImpl(void)
69         : __requestId(INVALID_REQUEST_ID)
70         , __restRequestId(INVALID_REQUEST_ID)
71         , __timeout(0)
72         , __percent(CONTENT_TRANSFER_DEFAULT_PROGRESS_INTERVAL)
73         , __timerStarted(false)
74         , __isBuffer(false)
75         , __destFilePath(L"")
76         , __pContentDownloadUserData(null)
77         , __pContentDownloadUserDataSequence(null)
78         , __pContentDownloadHandler(null)
79         , __pContentDownloadHandlerSequence(null)
80         , __pTransferEvent(null)
81         , __pTransferInfoList(null)
82         , __pTimer(null)
83 {
84
85 }
86
87 _ContentTransferImpl::~_ContentTransferImpl(void)
88 {
89                 initSlot = false;
90 }
91
92 _ContentTransferImpl*
93 _ContentTransferImpl::GetInstance(ContentTransfer& contentTransfer)
94 {
95         return contentTransfer.__pImpl;
96 }
97
98 const _ContentTransferImpl*
99 _ContentTransferImpl::GetInstance(const ContentTransfer& contentTransfer)
100 {
101         return contentTransfer.__pImpl;
102 }
103
104 result
105 _ContentTransferImpl::Construct(IContentTransferListener& listener)
106 {
107         // E_SUCCESS, E_OUT_OF_MEMORY, E_SYSTEM
108
109         ClearLastResult();
110         result r = E_SUCCESS;
111
112         std::unique_ptr<_ContentDownloadHandler> pContentDownloadHandler(new (std::nothrow) _ContentDownloadHandler);
113         SysTryReturn(NID_CNT, pContentDownloadHandler != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
114                         "[E_OUT_OF_MEMORY] Failed to construct ContentDownloadHandler.");
115
116         r = pContentDownloadHandler->Construct();
117         SysTryReturn(NID_CNT, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
118                         "[E_OUT_OF_MEMORY] Failed to construct ContentDownloadHandler.");
119
120         std::unique_ptr<_ContentDownloadHandler[]> pContentDownloadHandlerSequence(new (std::nothrow) _ContentDownloadHandler[MAX_DOWNLOAD_COUNT]);
121         SysTryReturn(NID_CNT, pContentDownloadHandlerSequence != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
122                         "[E_OUT_OF_MEMORY] Failed to construct ContentDownloadHandler array.");
123
124         for (int i = 0; i < MAX_DOWNLOAD_COUNT; i++)
125         {
126                 r = (pContentDownloadHandlerSequence.get())[i].Construct();
127                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
128                                    "[E_OUT_OF_MEMORY] Failed to construct ContentDownloadHandler array.");
129         }
130
131         std::unique_ptr<_ContentDownloadUserData> pContentDownloadUserData(new (std::nothrow) _ContentDownloadUserData);
132         SysTryReturn(NID_CNT, pContentDownloadUserData != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
133                         "[E_OUT_OF_MEMORY] Failed to construct ContentDownloadUserData.");
134
135         std::unique_ptr<_ContentDownloadUserData[]> pContentDownloadUserDataSequence(new (std::nothrow) _ContentDownloadUserData[MAX_DOWNLOAD_COUNT]);
136         SysTryReturn(NID_CNT, pContentDownloadUserDataSequence != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
137                         "[E_OUT_OF_MEMORY] Failed to construct ContentDownloadUserData.");
138
139         std::unique_ptr<_ContentTransferEvent> pTransferEvent(new (std::nothrow) _ContentTransferEvent);
140         SysTryReturn(NID_CNT, pTransferEvent != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
141                            "[E_OUT_OF_MEMORY] Failed to construct ContentTransferEvent.");
142
143         r = pTransferEvent->AddListener(listener, true);
144         SysTryReturn(NID_CNT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to perform AddListener to ContentTransferEvent.");
145
146         std::unique_ptr<ArrayList, AllElementsDeleter> pTransferInfoList(new (std::nothrow) ArrayList());
147         SysTryReturn(NID_CNT, pTransferInfoList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
148                            "[E_OUT_OF_MEMORY] Failed to construct ArrayList.");
149
150         r = pTransferInfoList->Construct();
151         SysTryReturn(NID_CNT, !IsFailed(r), r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
152                         "[E_OUT_OF_MEMORY] Failed to construct ArrayList.");
153
154         std::unique_ptr<Timer> pTimer(new (std::nothrow) Timer());
155         SysTryReturn(NID_CNT, pTimer != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Failed to construct Timer.");
156
157         r = pTimer->Construct(*this);
158         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to construct Timer.", GetErrorMessage(r));
159
160         InitializeEmptySlotInternal(pContentDownloadUserData.get());
161         r = GetLastResult();
162         SysTryReturn(NID_CNT, !IsFailed(r), r = E_SYSTEM, E_SYSTEM, "[E_SYSTEM] Failed to perform initiate the download slot.");
163
164         __pContentDownloadHandler = std::move(pContentDownloadHandler);
165         __pContentDownloadHandlerSequence = std::move(pContentDownloadHandlerSequence);
166
167         __pContentDownloadUserData = std::move(pContentDownloadUserData);
168         __pContentDownloadUserDataSequence = std::move(pContentDownloadUserDataSequence);
169
170         __pTransferEvent = std::move(pTransferEvent);
171
172         __pTransferInfoList = std::move(pTransferInfoList);
173
174         __pTimer = std::move(pTimer);
175
176         return r;
177 }
178
179 void
180 _ContentTransferImpl::InitializeEmptySlotInternal(_ContentDownloadUserData* pUserData)
181 {
182         ClearLastResult();
183         result r = E_SUCCESS;
184         bool check = false;
185         String tempPath(CONTENT_DOWNLOAD_TEMP_DIRECTORY);
186         int i = 0;
187
188         SysTryReturnVoidResult(NID_CNT, pUserData != null, r = E_SYSTEM,
189                         "[E_SYSTEM] ContentDownloadUserData instance must not be null.");
190
191         pUserData->SetMaxCount(MAX_DOWNLOAD_COUNT);
192
193         if (!initSlot)
194         {
195                 for (i = 0; i < MAX_DOWNLOAD_COUNT; i++)
196                 {
197                         pUserData->SetCheckDownloading(i, false);
198                 }
199
200                 String appId = _AppInfo::GetApplicationId();
201                 r = tempPath.Append(appId);
202                 SysTryReturnVoidResult(NID_CNT, !IsFailed(r), r, "[E_INVALID_ARG] Failed to perform Append operation.");
203
204                 // not exist
205                 check = _FileImpl::IsFileExist(tempPath);
206                 r = GetLastResult();
207                 SysTryReturnVoidResult(NID_CNT, !IsFailed(r), r,
208                                 "[%s] Failed to perform IsFileExist operation for [%ls] path.", GetErrorMessage(r), tempPath.GetPointer());
209
210                 if (!check)
211                 {
212                         r = Directory::Create(tempPath, false);
213                         SysTryReturnVoidResult(NID_CNT, !IsFailed(r), r,
214                                         "[%s] Failed to perform Create operation for [%ls] path.", GetErrorMessage(r), tempPath.GetPointer());
215                 }
216                 initSlot = true;
217         }
218
219         return;
220 }
221
222 int
223 _ContentTransferImpl::GetEmptySlotInternal(void) const
224 {
225         int i = 0;
226         for (i = 0; i < MAX_DOWNLOAD_COUNT; i++)
227         {
228                 if (!(__pContentDownloadUserData->GetCheckDownloading(i)))
229                 {
230                         return i;
231                 }
232         }
233         return -1;
234 }
235
236 void
237 _ContentTransferImpl::SetEmptySlotInternal(void)
238 {
239         for (int i = 0; i < MAX_DOWNLOAD_COUNT; i++)
240         {
241                 if (!((__pContentDownloadUserDataSequence.get())[i].GetSlotFlag()))
242                 {
243                         __pContentDownloadUserData->SetCheckDownloading(i, false);
244                 }
245         }
246 }
247
248 void
249 _ContentTransferImpl::SetUsedSlotInternal(int slot)
250 {
251         // TODO : If the error is occured in this command, set the mutex.
252         if (slot >= 0 && slot < MAX_DOWNLOAD_COUNT)
253         {
254                 __pContentDownloadUserData->SetCheckDownloading(slot, true);
255                 (__pContentDownloadUserDataSequence.get())[slot].SetSlotFlag(true);
256         }
257 }
258
259 result
260 _ContentTransferImpl::Cancel(RequestId reqId)
261 {
262         // E_SUCCESS, E_OBJ_NOT_FOUND, E_INVALID_ARG, E_INVALID_STATE
263
264         SysLog(NID_CNT, "Cancel the request ID(%d) in download.", reqId);
265
266         ClearLastResult();
267         result r = E_SUCCESS;
268         String destFilePath = null;
269         ContentTransferInfo* pContentTransferInfo = null;
270         int slot = -1;
271
272         SysAssertf(__pContentDownloadHandler != null, "Not yet constructed. Construct() should be called before use.");
273
274         pContentTransferInfo = GetContentTransferInfoByRequestId(reqId);
275         SysTryReturn(NID_CNT, pContentTransferInfo != null, r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
276                                 "[E_OBJ_NOT_FOUND] Unable to find the current Download operation.");
277
278         if (pContentTransferInfo->GetContentTransferStatus() == CONTENT_TRANSFER_STATUS_DOWNLOADING)
279         {
280                 slot = pContentTransferInfo->GetSlotId();
281                 r = (__pContentDownloadHandlerSequence.get())[slot].Cancel(pContentTransferInfo->GetRestRequestId(),
282                                                                                                                    &(__pContentDownloadUserDataSequence.get())[slot]);
283                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to perform Cancel operation.");
284         }
285         else
286         {
287                 // TODO : check timing issue.
288                 r = E_INVALID_STATE;
289                 SysLogException(NID_CNT, E_INVALID_STATE, "[E_INVALID_STATE] This [%d] request isn't under download.", reqId);
290         }
291
292         return r;
293 }
294
295 void
296 _ContentTransferImpl::SetDefaultTimeout(int sec)
297 {
298         if (sec > 0)
299         {
300                 __timeout = sec;
301         }
302         else
303         {
304                 __timeout = 0;
305         }
306 }
307
308 int
309 _ContentTransferImpl::GetDefaultTimeout(void) const
310 {
311         return __timeout;
312 }
313
314 result
315 _ContentTransferImpl::Remove(RequestId reqId)
316 {
317         // E_SUCCESS, E_OBJ_NOT_FOUND, E_OUT_OF_MEMORY, E_INVALID_STATE
318
319         SysLog(NID_CNT, "Remove the download request ID(%d) in queue.", reqId);
320
321         ClearLastResult();
322         result r = E_SUCCESS;
323         ContentTransferInfo* pTransferInfo = null;
324         std::unique_ptr<IEnumerator> pEnum;
325         int idx = 0;
326         int findIdx = -1;
327
328         SysAssertf(__pTransferInfoList != null, "Not yet constructed. Construct() should be called before use.");
329
330         pEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
331         SysTryReturn(NID_CNT, pEnum != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
332                            "[E_OUT_OF_MEMORY] Remove operation can not perform for [%d] request ID.", reqId);
333
334         while (pEnum->MoveNext() == E_SUCCESS)
335         {
336                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
337                 SysTryReturn(NID_CNT, pTransferInfo != null, r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
338                                    "[E_OBJ_NOT_FOUND] ContentTransferInfo instance must not be null.");
339
340                 if (pTransferInfo->GetRequestId() == reqId)
341                 {
342                         ContentTransferStatus status = pTransferInfo->GetContentTransferStatus();
343                         if (status == CONTENT_TRANSFER_STATUS_DOWNLOAD_READY ||
344                                 status == CONTENT_TRANSFER_STATUS_DOWNLOAD_COMPLETED)
345                         {
346                                 findIdx = idx;
347                                 break;
348                         }
349                         else if (status == CONTENT_TRANSFER_STATUS_DOWNLOADING)
350                         {
351                                 SysLogException(NID_CNT, E_INVALID_STATE, "[E_INVALID_STATE] This [%d] request operation is under download.", reqId);
352                                 return E_INVALID_STATE;
353                         }
354                 }
355                 idx++;
356         }
357
358         if (findIdx == -1)
359         {
360                 SysLogException(NID_CNT, E_OBJ_NOT_FOUND, "[E_OBJ_NOT_FOUND] [%d] request operation cannot found.", reqId);
361                 return E_OBJ_NOT_FOUND;
362         }
363         else
364         {
365                 __pTransferInfoList->RemoveAt(findIdx, true);
366                 r = GetLastResult();
367                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_OBJ_NOT_FOUND, E_OBJ_NOT_FOUND,
368                                                 "[E_OBJ_NOT_FOUND] Failed to perform RemoveAt operation for a content in transfer info list.");
369         }
370
371         return r;
372 }
373
374 result
375 _ContentTransferImpl::RemoveAll(void)
376 {
377         // E_SUCCESS, E_OUT_OF_MEMORY, E_INVALID_STATE
378
379         SysLog(NID_CNT, "Remove all download request ID in queue.");
380
381         ClearLastResult();
382         result r = E_SUCCESS;
383         ContentTransferInfo* pTransferInfo = null;
384         std::unique_ptr<IEnumerator> pTransferEnum;
385         std::unique_ptr<IEnumerator> pDeleteEnum;
386         ArrayList deleteList;
387
388         SysAssertf(__pTransferInfoList != null, "Not yet constructed. Construct() should be called before use.");
389
390         pTransferEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
391         SysTryReturn(NID_CNT, pTransferEnum != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
392                            "[E_OUT_OF_MEMORY] Failed to perform GetEnumeratorN operation.");
393
394         while (pTransferEnum->MoveNext() == E_SUCCESS)
395         {
396                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pTransferEnum->GetCurrent());
397                 SysTryReturn(NID_CNT, pTransferInfo != null, r = E_INVALID_STATE, r,
398                                 "[E_INVALID_STATE] ContentTransferInfo instance must not be null.");
399
400                 ContentTransferStatus status = pTransferInfo->GetContentTransferStatus();
401                 if (status == CONTENT_TRANSFER_STATUS_DOWNLOAD_READY || status == CONTENT_TRANSFER_STATUS_DOWNLOAD_COMPLETED)
402                 {
403                         deleteList.Add(*pTransferInfo);
404                 }
405         }
406
407         pDeleteEnum = std::unique_ptr<IEnumerator>(deleteList.GetEnumeratorN());
408         SysTryReturn(NID_CNT, pDeleteEnum != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
409                                    "[E_OUT_OF_MEMORY] Failed to perform GetEnumeratorN operation.");
410
411         while (pDeleteEnum->MoveNext() == E_SUCCESS)
412         {
413                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pDeleteEnum->GetCurrent());
414                 SysTryReturn(NID_CNT, pTransferInfo != null, r = E_INVALID_STATE, r,
415                                                 "[E_INVALID_STATE] ContentTransferInfo instance must not be null.");
416
417                 __pTransferInfoList->Remove(*pTransferInfo, true);
418                 r = GetLastResult();
419                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_STATE, E_INVALID_STATE,
420                                 "[E_INVALID_STATE] Failed to perform Remove operation for a content in transfer info list.");
421         }
422
423         return r;
424 }
425
426 result
427 _ContentTransferImpl::CancelAll(void)
428 {
429         // E_SUCCESS, E_OUT_OF_MEMORY, E_INVALID_STATE
430
431         SysLog(NID_CNT, "Cancel the all request ID in download.");
432
433         ClearLastResult();
434         result r = E_SUCCESS;
435         std::unique_ptr<IEnumerator> pEnum;
436         ContentTransferInfo* pTransferInfo = null;
437
438         SysAssertf(__pTransferInfoList != null && __pContentDownloadUserDataSequence != null,
439                         "Not yet constructed. Construct() should be called before use.");
440
441         pEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
442         SysTryReturn(NID_CNT, pEnum != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
443                            "[E_OUT_OF_MEMORY] Failed to perform GetEnumeratorN operation.");
444
445         while (pEnum->MoveNext() == E_SUCCESS)
446         {
447                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
448                 SysTryReturn(NID_CNT, pTransferInfo != null, r = E_INVALID_STATE, r,
449                                 "[E_INVALID_STATE] ContentTransferInfo instance must not be null.");
450
451                 ContentTransferStatus status = pTransferInfo->GetContentTransferStatus();
452                 if (status == CONTENT_TRANSFER_STATUS_DOWNLOADING)
453                 {
454                         SysLog(NID_CNT, "========== Canceled download slot : %d ==========", pTransferInfo->GetSlotId());
455
456                         r = (__pContentDownloadHandlerSequence.get())[pTransferInfo->GetSlotId()].Cancel(
457                                 pTransferInfo->GetRestRequestId(), &(__pContentDownloadUserDataSequence.get())[pTransferInfo->GetSlotId()]);
458                         SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_STATE, E_INVALID_STATE,
459                                         "[E_INVALID_STATE] Failed to perform Cancel operation.");
460                 }
461         }
462
463         return r;
464 }
465
466 Collection::IList*
467 _ContentTransferImpl::GetContentTransferInfoListN(void) const
468 {
469         std::unique_ptr<ArrayList, AllElementsDeleter> pTransferInfoList;
470         std::unique_ptr<IEnumerator> pEnum;
471         ContentTransferInfo* pTransferInfoCopy = null;
472         ContentTransferInfo* pTransferInfo = null;
473
474         SysAssertf(__pTransferInfoList != null, "Not yet constructed. Construct() should be called before use.");
475
476         pTransferInfoList = std::unique_ptr<ArrayList, AllElementsDeleter>(new (std::nothrow) ArrayList());
477         SysTryLogReturn(NID_CNT, pTransferInfoList != null, null, "Failed to construct ArrayList.");
478
479         pEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
480         SysTryLogReturn(NID_CNT, pEnum != null, null, "Failed to perform GetEnumeratorN operation.");
481
482         while (pEnum->MoveNext() == E_SUCCESS)
483         {
484                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
485                 SysTryLogReturn(NID_CNT, pTransferInfo != null, null, "ContentTransferInfo instance must not be null.");
486
487                 pTransferInfoCopy = pTransferInfo->CopyN();
488
489                 pTransferInfoList->Add(*pTransferInfoCopy);
490         }
491
492         return pTransferInfoList.release();
493 }
494
495 Collection::IList*
496 _ContentTransferImpl::GetContentTransferInfoListInProgressN(void) const
497 {
498         std::unique_ptr<ArrayList, AllElementsDeleter> pTransferInfoList;
499         std::unique_ptr<IEnumerator> pEnum;
500         ContentTransferInfo* pTransferInfoCopy = null;
501         ContentTransferInfo* pTransferInfo = null;
502
503         SysAssertf(__pTransferInfoList != null, "Not yet constructed. Construct() should be called before use.");
504
505         pTransferInfoList = std::unique_ptr<ArrayList, AllElementsDeleter>(new (std::nothrow) ArrayList());
506         SysTryLogReturn(NID_CNT, pTransferInfoList != null, null, "Failed to construct ArrayList.");
507
508         pEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
509         SysTryLogReturn(NID_CNT, pEnum != null, null, "Failed to perform GetEnumerator operation.");
510
511         while (pEnum->MoveNext() == E_SUCCESS)
512         {
513                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
514                 SysTryLogReturn(NID_CNT, pTransferInfo != null, null, "ContentTransferInfo instance must not be null.");
515
516                 ContentTransferStatus status = pTransferInfo->GetContentTransferStatus();
517                 if (status == CONTENT_TRANSFER_STATUS_DOWNLOADING)
518                 {
519                         pTransferInfoCopy = pTransferInfo->CopyN();
520                         pTransferInfoList->Add(*pTransferInfoCopy);
521                 }
522         }
523
524         return pTransferInfoList.release();
525 }
526
527 void
528 _ContentTransferImpl::SetProgressIntervalByPercent(int percent)
529 {
530         if (percent > 0 && percent <= 100)
531         {
532                 __percent = percent;
533         }
534         else
535         {
536                 __percent = 0;
537         }
538 }
539
540 result
541 _ContentTransferImpl::Download(const Utility::Uri& uri, int fileSize, const String& destFilePath, bool replace,
542                 RequestId& requestID, IContentTransferListener* pListener, int sec)
543 {
544         // E_SUCCESS, E_INVALID_ARG, E_INVALID_STATE, E_ILLEGAL_ACCESS, E_FILE_ALREADY_EXIST, E_PRIVILEGE_DENIED, E_IN_PROGRESS
545
546         SysLog(NID_CNT, "Download operation start with listener.");
547
548         ClearLastResult();
549         result r = E_SUCCESS;
550         String sourcePath(L"");
551         String destPath(L"");
552         String tempPath(L"");
553         String scheme(L"");
554         String checkName(L"");
555         String checkPath(L"");
556         int copySize = 0;
557         int maxSize = 1024;
558         int lengthString = 0;
559         FileAttributes fileAttr;
560
561         SysAssertf(__pContentDownloadHandler != null, "Not yet constructed. Construct() should be called before use.");
562
563         SysTryReturn(NID_CNT, fileSize >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
564                         "[E_INVALID_ARG] The size of the source file is less than 0.");
565         SysTryReturn(NID_CNT, !destFilePath.IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
566                         "[E_INVALID_ARG] The destination file path is empty.");
567         SysTryReturn(NID_CNT, !uri.ToString().IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
568                         "[E_INVALID_ARG] The source URI is empty.");
569         SysTryReturn(NID_CNT, !uri.GetHost().IsEmpty() && !uri.GetPath().IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
570                         "[E_INVALID_ARG] The source URI is empty.");
571         SysTryReturn(NID_CNT, sec >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
572                         "[E_INVALID_ARG] The timeout value is less than 0.");
573
574         destPath = destFilePath;
575
576         if (_FileImpl::IsSystemPath(destPath))
577         {
578                 SysLogException(NID_CNT, E_ILLEGAL_ACCESS, "[E_ILLEGAL_ACCESS] [%ls] path isn't permitted.", destFilePath.GetPointer());
579
580                 return E_ILLEGAL_ACCESS;
581         }
582
583         if (_FileImpl::IsFileExist(destPath))
584         {
585                 if (replace != true)
586                 {
587                         SysLogException(NID_CNT, E_FILE_ALREADY_EXIST, "[E_FILE_ALREADY_EXIST] The download file is already exist.");
588
589                         return E_FILE_ALREADY_EXIST;
590                 }
591
592                 SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destPath) == true || _FileImpl::IsAppPath(destPath) == true,
593                                 r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The file path is not a media or an app path.");
594
595                 // read-only, directory or file
596                 // check whether the destination file is read-only.
597                 // check whether the destination path without the file extension is a directory or not.
598                 r = _FileImpl::GetAttributes(destFilePath, fileAttr);
599                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
600                                 "[E_INVALID_ARG] Failed to perform GetAttributes operation for the destination path. ");
601                 SysTryReturn(NID_CNT, !fileAttr.IsDirectory(), r = E_ILLEGAL_ACCESS, E_ILLEGAL_ACCESS,
602                                 "[E_ILLEGAL_ACCESS] The file path is directory.");
603                 SysTryReturn(NID_CNT, !fileAttr.IsReadOnly(), r = E_ILLEGAL_ACCESS, E_ILLEGAL_ACCESS,
604                                 "[E_ILLEGAL_ACCESS] The file path is read only.");
605         }
606         else
607         {
608                 // check the destination file path
609                 // check the path
610                 SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destPath) == true || _FileImpl::IsAppPath(destPath) == true,
611                                 r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The file path is not a media or an app path.");
612
613                 // 1st: file name
614                 // check whether the destination path includes the file name
615                 checkName = _FileImpl::GetFileName(destPath);
616                 SysTryReturn(NID_CNT, !checkName.IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
617                                 "[E_INVALID_ARG] The file name is empty.");
618
619                 // 2nd: parent directory
620                 lengthString = destFilePath.String::GetLength();
621                 r = destPath.String::LastIndexOf('/', lengthString - 1, copySize);
622                 SysTryReturn(NID_CNT, copySize > 0 && copySize < maxSize, r = E_INVALID_ARG, E_INVALID_ARG,
623                                 "[E_INVALID_ARG] The length of path is invalid size.");
624
625                 // copy the parent path
626                 r = destPath.SubString(0, copySize + 1, checkPath);
627                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
628                                 "[E_INVALID_ARG] Failed to perform SubString operation.");
629
630                 // check the validation of the parent path
631                 r = _FileImpl::GetAttributes(checkPath, fileAttr);
632                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
633                                 "[E_INVALID_ARG] Failed to perform GetAttributes operation.");
634                 SysTryReturn(NID_CNT, fileAttr.IsDirectory(), r = E_ILLEGAL_ACCESS, E_ILLEGAL_ACCESS,
635                                 "[E_ILLEGAL_ACCESS] The path is not directory path.");
636         }
637
638         __destFilePath = destPath;
639         scheme = uri.GetScheme();
640
641         if (scheme.CompareTo(L"http") == 0 || scheme.CompareTo(L"https") == 0)
642         {
643                 sourcePath = uri.GetEncodedString();
644
645                 r = AddTransferItem(uri, destPath, sourcePath, fileSize, CONTENT_TRANSFER_STATUS_DOWNLOAD_READY,
646                                 pListener, sec, false, requestID);
647                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to add a transfer item to queue.", GetErrorMessage(r));
648
649                 // TODO : if timer is started, it doesn't need call it..
650                 ContentTransferHandler();
651                 r = GetLastResult();
652                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to handle the content transfer.", GetErrorMessage(r));
653         }
654         else
655         {
656                 SysLogException(NID_CNT, E_INVALID_ARG, "[E_INVALID_ARG] It is unsupported URI(%ls) address format.", uri.ToString().GetPointer());
657
658                 return E_INVALID_ARG;
659         }
660
661         return r;
662 }
663
664 result
665 _ContentTransferImpl::DownloadToBuffer(const Utility::Uri& uri, int fileSize, RequestId& reqId,
666                 IContentTransferListener* pListener, int sec)
667 {
668         // E_SUCCESS, E_INVALID_ARG, E_INVALID_STATE, E_PRIVILEGE_DENIED
669
670         SysLog(NID_CNT, "DownloadToBuffer operation start with listener.");
671
672         ClearLastResult();
673         result r = E_SUCCESS;
674         String sourcePath(L"");
675         String scheme(L"");
676         long long ticks = 0;
677
678         SysAssertf(__pContentDownloadHandler != null, "Not yet constructed. Construct() should be called before use.");
679
680         SysTryReturn(NID_CNT, fileSize >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
681                         "[E_INVALID_ARG] The size of the source file is less than 0.");
682         SysTryReturn(NID_CNT, !uri.ToString().IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
683                         "[E_INVALID_ARG] The source URI is empty.");
684         SysTryReturn(NID_CNT, !uri.GetHost().IsEmpty() && !uri.GetPath().IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
685                         "[E_INVALID_ARG] The source URI is empty.");
686         SysTryReturn(NID_CNT, sec >= 0, E_INVALID_ARG, E_INVALID_ARG,
687                         "[E_INVALID_ARG] The timeout value is less than 0.");
688
689         scheme = uri.GetScheme();
690
691         if (scheme.CompareTo(L"http") == 0 || scheme.CompareTo(L"https") == 0)
692         {
693                 r = _SystemTimeImpl::GetTicks(ticks);
694                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_STATE, E_INVALID_STATE,
695                                 "[E_INVALID_STATE] Failed to perform GetTicks operation.");
696
697                 String tempFilePath(CONTENT_DOWNLOAD_TEMP_DIRECTORY);
698                 r = tempFilePath.Append(_AppInfo::GetApplicationId());
699                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to perform Append operation.");
700
701                 r = tempFilePath.Append(L"/downloadtempfile");
702                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to perform Append operation.");
703
704                 r = tempFilePath.Append(ticks);
705                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_STATE, E_INVALID_STATE,
706                                 "[E_INVALID_STATE] Failed to append long long type to temporary file path.");
707
708                 r = tempFilePath.Append(downloadRequestId);
709                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
710                                 "[E_INVALID_ARG] Failed to append int type to temporary file path.");
711
712                 sourcePath = uri.GetEncodedString();
713
714                 r = AddTransferItem(uri, tempFilePath, sourcePath, fileSize,
715                                 CONTENT_TRANSFER_STATUS_DOWNLOAD_READY, pListener, sec, true, reqId);
716                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
717                                 "[E_INVALID_ARG] Failed to add a transfer item to queue.");
718
719                 // TODO : if timer is started, it doesn't need call it..
720                 __destFilePath = tempFilePath;
721                 ContentTransferHandler();
722                 r = GetLastResult();
723                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to handle the content transfer.", GetErrorMessage(r));
724         }
725         else
726         {
727                 SysLogException(NID_CNT, E_INVALID_ARG, "[E_INVALID_ARG] It is unsupported URI(%ls) address format.", uri.ToString().GetPointer());
728
729                 return E_INVALID_ARG;
730         }
731
732         return r;
733 }
734
735 result
736 _ContentTransferImpl::Download(const Utility::Uri& uri, const String& filePath,
737                                                            RequestId& reqId, bool replace, int timeout, int progressInterval)
738 {
739         // E_SUCCESS, E_PRIVILEGE_DENIED, E_INVALID_ARG, E_INVALID_STATE, E_ILLEGAL_ACCESS, E_FILE_ALREADY_EXIST, E_IN_PROGRESS, E_OUT_OF_MEMORY, E_SYSTEM
740
741         SysLog(NID_CNT, "Download operation start without listener.");
742
743         ClearLastResult();
744         result r = E_SUCCESS;
745         String srcFilePath(L"");
746         String scheme(L"");
747
748         SysAssertf(__pContentDownloadHandler != null, "Not yet constructed. Construct() should be called before use.");
749
750         SysTryReturn(NID_CNT, !filePath.IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
751                                 "[E_INVALID_ARG] The destination file path is empty.");
752         SysTryReturn(NID_CNT, !uri.ToString().IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
753                                 "[E_INVALID_ARG] The source URI is empty.");
754         SysTryReturn(NID_CNT, !uri.GetHost().IsEmpty() && !uri.GetPath().IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
755                                 "[E_INVALID_ARG] The source URI is empty.");
756         SysTryReturn(NID_CNT, timeout >= 0, r = E_INVALID_ARG, E_INVALID_ARG,
757                                 "[E_INVALID_ARG] The timeout value is less than 0.");
758         SysTryReturn(NID_CNT, progressInterval >= 0 && progressInterval <= 100, r = E_INVALID_ARG, E_INVALID_ARG,
759                                 "[E_INVALID_ARG] The progress interval is less than 0.");
760
761         if (!_AppInfo::IsOspCompat())
762         {
763                 if (filePath.StartsWith(CONTENT_DOWNLOAD_PATH_MEDIA, 0) || filePath.StartsWith(CONTENT_DOWNLOAD_PATH_MEDIA_MMC, 0) ||
764                                 filePath.StartsWith(CONTENT_DOWNLOAD_PATH_HOME, 0) || filePath.StartsWith(CONTENT_DOWNLOAD_PATH_HOME_MMC, 0))
765                 {
766                         SysLogException(NID_CNT, E_INVALID_ARG,
767                                         "[E_INVALID_ARG] /Media/ , /Storagecard/Media/ , /Home/ , /HomeExt/ are not supported from Tizen 2.0.");
768
769                         return E_INVALID_ARG;
770                 }
771                 if (!(filePath.StartsWith(Tizen::App::App::GetInstance()->GetAppRootPath(), 0) || filePath.StartsWith(Environment::GetMediaPath(), 0) ||
772                                 filePath.StartsWith(Environment::GetExternalStoragePath(), 0)))
773                 {
774                         SysLogException(NID_CNT, E_INVALID_ARG,
775                                         "[E_INVALID_ARG] The [%ls] path is not supported.", filePath.GetPointer());
776
777                         return E_INVALID_ARG;
778                 }
779         }
780         else
781         {
782                 // prior to 2.0
783                 if (filePath.StartsWith(Tizen::App::App::GetInstance()->GetAppRootPath(), 0) || filePath.StartsWith(Environment::GetMediaPath(), 0) ||
784                                 filePath.StartsWith(Environment::GetExternalStoragePath(), 0))
785                 {
786                         SysLogException(NID_CNT, E_INVALID_ARG,
787                                         "[E_INVALID_ARG] This [%ls] path can be used from Tizen 2.0.", filePath.GetPointer());
788
789                         return E_INVALID_ARG;
790                 }
791                 if (!(filePath.StartsWith(CONTENT_DOWNLOAD_PATH_MEDIA, 0) || filePath.StartsWith(CONTENT_DOWNLOAD_PATH_MEDIA_MMC, 0) ||
792                                 filePath.StartsWith(CONTENT_DOWNLOAD_PATH_HOME, 0) || filePath.StartsWith(CONTENT_DOWNLOAD_PATH_HOME_MMC, 0)))
793                 {
794                         SysLogException(NID_CNT, E_INVALID_ARG,
795                                         "[E_INVALID_ARG] The [%ls] is not supported.", filePath.GetPointer());
796
797                         return E_INVALID_ARG;
798                 }
799         }
800
801         __destFilePath = filePath;
802
803         r = CheckDestPath(__destFilePath, replace);
804         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to perform CheckDestPath operation.", GetErrorMessage(r));
805
806         scheme = uri.GetScheme();
807
808         if (scheme.CompareTo(L"http") == 0 || scheme.CompareTo(L"https") == 0)
809         {
810                 srcFilePath = uri.GetEncodedString();
811
812                 r = AddTransferItem(uri, __destFilePath, srcFilePath, CONTENT_TRANSFER_STATUS_DOWNLOAD_READY,
813                                                         timeout, progressInterval, false, reqId);
814                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to add a transfer item to queue.", GetErrorMessage(r));
815         }
816         else
817         {
818                 SysLogException(NID_CNT, E_INVALID_ARG,
819                                 "[E_INVALID_ARG] It is unsupported URI(%ls) address format.", uri.ToString().GetPointer());
820
821                 return E_INVALID_ARG;
822         }
823
824         ContentTransferHandler();
825         r = GetLastResult();
826         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to handle the content transfer.", GetErrorMessage(r));
827
828         return r;
829 }
830
831 result
832 _ContentTransferImpl::DownloadToBuffer(const Utility::Uri& uri, RequestId& reqId, int timeout, int progressInterval)
833 {
834         // E_SUCCESS, E_PRIVILEGE_DENIED, E_INVALID_ARG, E_INVALID_STATE, E_ILLEGAL_ACCESS, E_IN_PROGRESS, E_OUT_OF_MEMORY
835
836         SysLog(NID_CNT, "DownloadToBuffer operation start without listener.");
837         ClearLastResult();
838         result r = E_SUCCESS;
839         String srcFilePath(L"");
840         String scheme(L"");
841         long long ticks = 0;
842
843         SysAssertf(__pContentDownloadHandler != null, "Not yet constructed. Construct() should be called before use.");
844
845         SysTryReturn(NID_CNT, !uri.ToString().IsEmpty(), E_INVALID_ARG, E_INVALID_ARG,
846                                 "[E_INVALID_ARG] The source URI is empty.");
847         SysTryReturn(NID_CNT, !uri.GetHost().IsEmpty() && !uri.GetPath().IsEmpty(), E_INVALID_ARG, E_INVALID_ARG,
848                                 "[E_INVALID_ARG] The source URI is empty.");
849         SysTryReturn(NID_CNT, timeout >= 0, E_INVALID_ARG, E_INVALID_ARG,
850                                 "[E_INVALID_ARG] The timeout value is less than 0.");
851         SysTryReturn(NID_CNT, progressInterval >= 0 && progressInterval <= 100, E_INVALID_ARG, E_INVALID_ARG,
852                                 "[E_INVALID_ARG] The progress interval is less than 0.");
853
854         scheme = uri.GetScheme();
855         if (scheme.CompareTo(L"http") == 0 || scheme.CompareTo(L"https") == 0)
856         {
857                 r = _SystemTimeImpl::GetTicks(ticks);
858                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to perform GetTicks operation.", GetErrorMessage(r));
859
860                 String tempDestFilePath(CONTENT_DOWNLOAD_TEMP_DIRECTORY);
861                 r = tempDestFilePath.Append(_AppInfo::GetApplicationId());
862                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to perform Append operation.");
863
864                 r = tempDestFilePath.Append(L"/downloadtempfile");
865                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to perform Append operation.");
866
867                 r = tempDestFilePath.Append(ticks);
868                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to append long long type to temporary file path.", GetErrorMessage(r));
869
870                 r = tempDestFilePath.Append(downloadRequestId);
871                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to append int type to temporary file path.", GetErrorMessage(r));
872
873                 srcFilePath = uri.GetEncodedString();
874
875                 r = AddTransferItem(uri, tempDestFilePath, srcFilePath, CONTENT_TRANSFER_STATUS_DOWNLOAD_READY,
876                                                         timeout, progressInterval, true, reqId);
877                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to add a transfer item to queue.", GetErrorMessage(r));
878         }
879         else
880         {
881                 SysLogException(NID_CNT, E_INVALID_ARG,
882                                 "[E_INVALID_ARG] It is unsupported URI(%ls) address format.", uri.ToString().GetPointer());
883
884                 return E_INVALID_ARG;
885         }
886
887         ContentTransferHandler();
888         r = GetLastResult();
889         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to handle the content transfer.", GetErrorMessage(r));
890
891         return r;
892 }
893
894 void
895 _ContentTransferImpl::OnTimerExpired(Runtime::Timer& timer)
896 {
897         ClearLastResult();
898         bool check = false;
899         check = ContentTransferHandler();
900
901         SysAssertf(__pTimer != null, "Not yet constructed. Construct() should be called before use.");
902
903         if (check == true)
904         {
905                 __pTimer->Start(CONTENT_DOWNLOAD_CHECKING_PERIOD);
906                 __timerStarted = true;
907         }
908         else
909         {
910                 __timerStarted = false;
911         }
912 }
913
914 RequestId
915 _ContentTransferImpl::GetRequestId(void) const
916 {
917         return ++downloadRequestId;
918 }
919
920 ContentTransferInfo*
921 _ContentTransferImpl::GetContentTransferInfoByRequestId(RequestId requestId) const
922 {
923         ClearLastResult();
924         result r = E_SUCCESS;
925         std::unique_ptr<IEnumerator> pEnum;
926         ContentTransferInfo* pTransferInfo = null;
927
928         pEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
929
930         if (pEnum == null)
931         {
932                 r = GetLastResult();
933                 SysLogException(NID_CNT, r, "[%s] Failed to perform GetEnumeratorN operation.", GetErrorMessage(r));
934                 return null;
935         }
936
937         while (pEnum->MoveNext() == E_SUCCESS)
938         {
939                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
940                 SysTryReturn(NID_CNT, pTransferInfo != null, null, E_INVALID_ARG,
941                                    "[E_INVALID_ARG] ContentTransferInfo instance must not be null.");
942
943                 if (pTransferInfo->GetRequestId() == requestId)
944                 {
945                         break;
946                 }
947                 pTransferInfo = null;
948         }
949
950         return pTransferInfo;
951 }
952
953 void
954 _ContentTransferImpl::StartTimer(void)
955 {
956         ClearLastResult();
957         result r = E_SUCCESS;
958
959         if (!(__timerStarted))
960         {
961                 r = __pTimer->Start(CONTENT_DOWNLOAD_CHECKING_PERIOD);
962                 SysTryReturnVoidResult(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, "[E_INVALID_ARG] Failed to start timer.");
963
964                 __timerStarted = true;
965         }
966 }
967
968 result
969 _ContentTransferImpl::GetEmptySlot(int& slot) const
970 {
971         ClearLastResult();
972         result r = E_SUCCESS;
973
974         slot = GetEmptySlotInternal();
975
976         if (slot < 0 || slot > MAX_DOWNLOAD_COUNT)
977         {
978                 r = E_OBJ_NOT_FOUND;
979                 SysLog(NID_CNT, "Failed to get empty slot for download.");
980         }
981
982         return r;
983 }
984
985 result
986 _ContentTransferImpl::CheckDestPath(const String& destPath, bool replace)
987 {
988         result r = E_SUCCESS;
989         String destFilePath(L"");
990         String checkName(L"");
991         String checkPath(L"");
992         FileAttributes fileAttr;
993         int copySize = 0;
994         int maxSize = 1024;
995         int lengthString = 0;
996         Directory dir;
997
998         destFilePath = destPath;
999         SysTryReturn(NID_CNT, !destFilePath.IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
1000                                 "[E_INVALID_ARG] The destination file path is empty.");
1001
1002         if (!_AppInfo::IsOspCompat())
1003         {
1004                 if (!(destFilePath.String::StartsWith(Environment::GetMediaPath(), 0) ||
1005                           destFilePath.String::StartsWith(Environment::GetExternalStoragePath(), 0) ||
1006                           destFilePath.String::StartsWith(Tizen::App::App::GetInstance()->GetAppRootPath(), 0)))
1007                 {
1008                         SysLogException(NID_CNT, E_INVALID_ARG, "[E_INVALID_ARG] The destination path is not allowed path.");
1009                         return E_INVALID_ARG;
1010                 }
1011         }
1012         else
1013         {
1014                 // the allowed destination path
1015                 // /Media, /Storagecard/Media
1016                 // /Home, /HomeExt
1017                 if (!(destFilePath.String::StartsWith(CONTENT_DOWNLOAD_PATH_MEDIA, 0) ||
1018                           destFilePath.String::StartsWith(CONTENT_DOWNLOAD_PATH_MEDIA_MMC, 0) ||
1019                           destFilePath.String::StartsWith(CONTENT_DOWNLOAD_PATH_HOME, 0) ||
1020                           destFilePath.String::StartsWith(CONTENT_DOWNLOAD_PATH_HOME_MMC, 0)))
1021                 {
1022                         SysLogException(NID_CNT, E_INVALID_ARG, "[E_INVALID_ARG] The destination path is not allowed path.");
1023                         return E_INVALID_ARG;
1024                 }
1025         }
1026
1027         //check overwrite
1028         if (_FileImpl::IsFileExist(destFilePath) == true)
1029         {
1030                 // not allowed overwrite
1031                 if (replace != true)
1032                 {
1033                         SysLogException(NID_CNT, E_FILE_ALREADY_EXIST, "[E_FILE_ALREADY_EXIST] The file already exists in destination path.");
1034                         return E_FILE_ALREADY_EXIST;
1035                 }
1036
1037                 // allowed overwrite
1038                 r = _FileImpl::GetAttributes(destFilePath, fileAttr);
1039                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
1040                                 "[E_INVALID_ARG] Failed to perform GetAttributes operation. ");
1041                 SysTryReturn(NID_CNT, !(fileAttr.IsDirectory()), r = E_ILLEGAL_ACCESS, E_ILLEGAL_ACCESS,
1042                                    "[E_ILLEGAL_ACCESS] The file path is directory path.");
1043                 SysTryReturn(NID_CNT, !(fileAttr.IsReadOnly()), r = E_ILLEGAL_ACCESS, E_ILLEGAL_ACCESS,
1044                                    "[E_ILLEGAL_ACCESS] The file can only read.");
1045         }
1046         else
1047         {
1048
1049                 if (_AppInfo::GetApiVersion() == _API_VERSION_2_0 && _AppInfo::IsOspCompat())
1050                 {
1051                         // check the destination file path
1052                         // check the path
1053                         SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destFilePath) == true || _FileImpl::IsAppPath(destFilePath) == true,
1054                                         r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The file path is not a media or an app path.");
1055                 }
1056
1057                 // 1st: file name
1058                 // check whether the destination path includes the file name
1059                 checkName = _FileImpl::GetFileName(destFilePath);
1060                 SysTryReturn(NID_CNT, !checkName.IsEmpty(), r = E_INVALID_ARG, E_INVALID_ARG,
1061                                    "[E_INVALID_ARG] Failed to get the file name from a path.");
1062
1063                 // 2nd: parent directory
1064                 lengthString = destFilePath.String::GetLength();
1065                 r = destFilePath.String::LastIndexOf('/', lengthString - 1, copySize);
1066                 SysTryReturn(NID_CNT, copySize > 0 && copySize < maxSize, r = E_INVALID_ARG, E_INVALID_ARG,
1067                                 "[E_INVALID_ARG] Failed to get the size of path.");
1068
1069                 // copy the parent path
1070                 r = destFilePath.SubString(0, copySize + 1, checkPath);
1071                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
1072                                 "[E_INVALID_ARG] Failed to perform SubString operation.");
1073
1074                 if (!_AppInfo::IsOspCompat())
1075                 {
1076                         SysTryReturn(NID_CNT, destFilePath.String::StartsWith(Environment::GetMediaPath(), 0) ||
1077                                           destFilePath.String::StartsWith(Environment::GetExternalStoragePath(), 0) ||
1078                                         _FileImpl::IsAppPath(destFilePath) == true,
1079                                         r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The path is invalid media path.");
1080
1081                         if (!(_FileImpl::IsFileExist(checkPath)))
1082                         {
1083                                 r = dir.Create(checkPath);
1084                                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
1085                                                 "[E_INVALID_ARG] Failed to create the directory.");
1086                         }
1087                 }
1088
1089                 // check the validation of the parent path
1090                 r = _FileImpl::GetAttributes(checkPath, fileAttr);
1091                 SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG,
1092                                 "[E_INVALID_ARG] Failed to perform GetAttributes operation.");
1093                 SysTryReturn(NID_CNT, fileAttr.IsDirectory() == true, r = E_ILLEGAL_ACCESS, E_ILLEGAL_ACCESS,
1094                                 "[E_ILLEGAL_ACCESS] The path is not a directory path.");
1095         }
1096
1097         return r;
1098 }
1099
1100 result
1101 _ContentTransferImpl::CheckDownloadStatus(const Uri& uri, const String& destPath)
1102 {
1103         ClearLastResult();
1104         std::unique_ptr<IEnumerator> pEnum;
1105         ContentTransferInfo* pTransferInfoTemp = null;
1106         ContentTransferStatus statusTemp = CONTENT_TRANSFER_STATUS_NONE;
1107         result r = E_SUCCESS;
1108
1109         pEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
1110         SysTryReturn(NID_CNT, pEnum != null, r = E_ILLEGAL_ACCESS, E_ILLEGAL_ACCESS,
1111                            "[%s] Failed to perform GetEnumeratorN operation.", GetErrorMessage(r));
1112
1113         while (pEnum->MoveNext() == E_SUCCESS)
1114         {
1115                 pTransferInfoTemp = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
1116                 SysTryReturn(NID_CNT, pTransferInfoTemp != null, r = E_INVALID_STATE, E_INVALID_STATE,
1117                                    "[E_INVALID_STATE] ContentTransferInfo instance must not be null.");
1118
1119                 statusTemp = pTransferInfoTemp->GetContentTransferStatus();
1120
1121                 if (statusTemp == CONTENT_TRANSFER_STATUS_DOWNLOAD_READY ||
1122                         statusTemp == CONTENT_TRANSFER_STATUS_DOWNLOADING)
1123                 {
1124                         if (destPath.CompareTo(pTransferInfoTemp->GetDestPath()) == 0)
1125                         {
1126                                 if (uri.CompareTo(pTransferInfoTemp->GetUri()) == 0)
1127                                 {
1128                                         SysLogException(NID_CNT, E_IN_PROGRESS, "[E_IN_PROGRESS] Transfer is in progress.");
1129                                         return E_IN_PROGRESS;
1130                                 }
1131                                 else
1132                                 {
1133                                         SysLogException(NID_CNT, E_ILLEGAL_ACCESS, "[E_ILLEGAL_ACCESS] Access to source is illegal access.");
1134                                         return E_ILLEGAL_ACCESS;
1135                                 }
1136                         }
1137                 }
1138         }
1139
1140         return r;
1141 }
1142
1143 result
1144 _ContentTransferImpl::AddTransferItem(const Uri& uri, const String& destPath, const String& sourcePath, int sourceFileSize,
1145                 ContentTransferStatus status, IContentTransferListener* pListener, int sec, bool isBuffer, RequestId& requestId)
1146 {
1147         ClearLastResult();
1148         result r = E_SUCCESS;
1149         std::unique_ptr<IEnumerator> pEnum;
1150         std::unique_ptr<ContentTransferInfo> pTransferInfo;
1151         ContentTransferInfo* pTransferInfoTemp = null;
1152         ContentTransferStatus statusTemp = CONTENT_TRANSFER_STATUS_NONE;
1153         requestId = INVALID_REQUEST_ID;
1154
1155         SysAssertf(__pTransferInfoList != null, "Not yet constructed. Construct() should be called before use.");
1156
1157         pEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
1158         SysTryReturn(NID_CNT, pEnum != null, r = E_ILLEGAL_ACCESS, E_ILLEGAL_ACCESS,
1159                         "[E_ILLEGAL_ACCESS] Failed to perform GetEnumeratorN operation.");
1160
1161         while (pEnum->MoveNext() == E_SUCCESS)
1162         {
1163                 pTransferInfoTemp = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
1164                 SysTryReturn(NID_CNT, pTransferInfoTemp != null, r = E_INVALID_ARG, E_INVALID_ARG,
1165                                    "[E_INVALID_ARG] ContentTransferInfo instance must not be null.");
1166
1167                 statusTemp = pTransferInfoTemp->GetContentTransferStatus();
1168
1169                 if (statusTemp == CONTENT_TRANSFER_STATUS_DOWNLOAD_READY || statusTemp == CONTENT_TRANSFER_STATUS_DOWNLOADING)
1170                 {
1171                         if (destPath.CompareTo(pTransferInfoTemp->GetDestPath()) == 0)
1172                         {
1173                                 if (uri.CompareTo(pTransferInfoTemp->GetUri()) == 0)
1174                                 {
1175                                         SysLogException(NID_CNT, E_IN_PROGRESS, "[E_IN_PROGRESS] The request is already in progress.");
1176                                         return E_IN_PROGRESS;
1177                                 }
1178                                 else
1179                                 {
1180                                         SysLogException(NID_CNT, E_ILLEGAL_ACCESS,
1181                                                         "[E_ILLEGAL_ACCESS] The destination path [%ls] is already in progress.", destPath.GetPointer());
1182                                         return E_ILLEGAL_ACCESS;
1183                                 }
1184                         }
1185                 }
1186         }
1187
1188         pTransferInfo = std::unique_ptr<ContentTransferInfo>(new (std::nothrow) ContentTransferInfo);
1189         SysTryReturn(NID_CNT, pTransferInfo != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
1190                         "[E_OUT_OF_MEMORY] Failed to construct ContentTransferInfo.");
1191
1192         requestId = GetRequestId();
1193
1194         pTransferInfo->SetAllInfo(requestId, uri, destPath, sourcePath, sourceFileSize, status);
1195
1196         if (pListener)
1197         {
1198                 pTransferInfo->SetListener(pListener);
1199         }
1200
1201         if (sec > 0)
1202         {
1203                 __timeout = sec;
1204                 pTransferInfo->SetTimeout(sec);
1205         }
1206         else
1207         {
1208                 __timeout = 0;
1209                 pTransferInfo->SetTimeout(0);
1210         }
1211
1212         if (__percent > 0 && __percent <= 100)
1213         {
1214                 pTransferInfo->SetProgressInterval(__percent);
1215         }
1216         else
1217         {
1218                 pTransferInfo->SetProgressInterval(0);
1219         }
1220
1221         if (isBuffer == true)
1222         {
1223                 __isBuffer = isBuffer;
1224                 pTransferInfo->SetIsBuffer(true);
1225         }
1226
1227         r = __pTransferInfoList->Add(*(pTransferInfo.release()));
1228         SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to add item to info list.");
1229
1230         return r;
1231 }
1232
1233 result
1234 _ContentTransferImpl::AddTransferItem(const Uri& uri, const String& destPath, const String& sourcePath,
1235                                                                           ContentTransferStatus status, int timeout, int interval, bool isBuffer, RequestId& requestId)
1236 {
1237         ClearLastResult();
1238         result r = E_SUCCESS;
1239         std::unique_ptr<ContentTransferInfo> pTransferInfo;
1240         requestId = INVALID_REQUEST_ID;
1241
1242         r = CheckDownloadStatus(uri, destPath);
1243         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to perform CheckDownloadStatus operation.", GetErrorMessage(r));
1244
1245         // pTransferInfo will be deallocated in the Response routine
1246         pTransferInfo = std::unique_ptr<ContentTransferInfo>(new (std::nothrow) ContentTransferInfo);
1247         SysTryReturn(NID_CNT, pTransferInfo != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
1248                                 "[%s] Failed to construct ContentTransferInfo.", GetErrorMessage(r));
1249
1250         requestId = GetRequestId();
1251
1252         pTransferInfo->SetAllInfo(requestId, uri, destPath, sourcePath, 0, status);
1253
1254         if (timeout > 0)
1255         {
1256                 __timeout = timeout;
1257                 pTransferInfo->SetTimeout(timeout);
1258         }
1259         else
1260         {
1261                 __timeout = 0;
1262                 pTransferInfo->SetTimeout(0);
1263         }
1264
1265         if (interval > 0 && interval <= 100)
1266         {
1267                 __percent = interval;
1268                 pTransferInfo->SetProgressInterval(interval);
1269         }
1270         else
1271         {
1272                 __percent = 0;
1273                 pTransferInfo->SetProgressInterval(0);
1274         }
1275
1276         if (isBuffer == true)
1277         {
1278                 __isBuffer = isBuffer;
1279                 pTransferInfo->SetIsBuffer(true);
1280         }
1281
1282         r = __pTransferInfoList->Add(*(pTransferInfo.release()));
1283         SysTryReturn(NID_CNT, !IsFailed(r), r = E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] Failed to add item to info list.");
1284
1285         return r;
1286 }
1287
1288 result
1289 _ContentTransferImpl::SetDownloadSlotInfo(ContentTransferInfo* pTransferInfo, int& slot)
1290 {
1291         ClearLastResult();
1292         result r = E_SUCCESS;
1293         String destPath(L"");
1294
1295         SysAssertf(__pContentDownloadHandler != null, "Not yet constructed. Construct() should be called before use.");
1296
1297         SysTryReturn(NID_CNT, pTransferInfo != null, r = E_INVALID_ARG, E_INVALID_ARG,
1298                                 "[E_INVALID_ARG] ContentTransferInfo instance must not be null.");
1299
1300         destPath = pTransferInfo->GetDestPath();
1301
1302         r = GetEmptySlot(slot);
1303         SysLog(NID_CNT, "Set the download slot [%d].", slot);
1304         SysTryReturn(NID_CNT, !IsFailed(r) && slot != -1, r = E_INVALID_ARG, E_INVALID_ARG,
1305                         "[E_INVALID_ARG] Failed to get the empty slot.");
1306
1307         SetUsedSlotInternal(slot);
1308
1309         (__pContentDownloadHandlerSequence.get())[slot].SetSlot(slot);
1310         (__pContentDownloadHandlerSequence.get())[slot].SetRequestId(pTransferInfo->GetRequestId());
1311         (__pContentDownloadHandlerSequence.get())[slot].SetTimeout(pTransferInfo->GetTimeout());
1312         (__pContentDownloadHandlerSequence.get())[slot].SetProgressIntervalByPercent(pTransferInfo->GetProgressInterval());
1313         (__pContentDownloadHandlerSequence.get())[slot].SetDownloadPath(destPath);
1314
1315         (__pContentDownloadUserDataSequence.get())[slot].SetSlot(slot);
1316         (__pContentDownloadUserDataSequence.get())[slot].SetContentTransferInfo(pTransferInfo);
1317         (__pContentDownloadUserDataSequence.get())[slot].SetRequestId(pTransferInfo->GetRequestId());
1318         (__pContentDownloadUserDataSequence.get())[slot].SetPercent(pTransferInfo->GetProgressInterval());
1319         (__pContentDownloadUserDataSequence.get())[slot].SetContentTransferEvent(__pTransferEvent.get());
1320         (__pContentDownloadUserDataSequence.get())[slot].SetDestPath(destPath);
1321
1322         if (__isBuffer == true)
1323         {
1324                 (__pContentDownloadUserDataSequence.get())[slot].SetDownloadBufferFlag(true);
1325         }
1326
1327         pTransferInfo->SetSlotId(slot);
1328
1329         return r;
1330 }
1331
1332 result
1333 _ContentTransferImpl::RequestErrorEvent(result requestErrorCode, ContentTransferInfo* pTransferInfo)
1334 {
1335         ClearLastResult();
1336         result r = E_SUCCESS;
1337         std::unique_ptr<_ContentTransferEventArg> pTransferEventArg;
1338
1339         pTransferEventArg = std::unique_ptr<_ContentTransferEventArg>(new (std::nothrow) _ContentTransferEventArg);
1340         SysTryReturn(NID_CNT, pTransferEventArg != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
1341                                 "[E_OUT_OF_MEMORY] Failed to construct ContentTransferEventArg.");
1342
1343         pTransferEventArg->SetResult(requestErrorCode);
1344
1345         if (pTransferInfo->GetIsBuffer() == true)
1346         {
1347                 pTransferEventArg->SetEventType(Content::CONTENT_TRANSFER_EVENT_DOWNLOAD_TO_BUFFER_COMPLETED);
1348
1349         }
1350         else
1351         {
1352                 pTransferEventArg->SetEventType(Content::CONTENT_TRANSFER_EVENT_DOWNLOAD_COMPLETED);
1353         }
1354
1355         pTransferEventArg->SetRequestId(pTransferInfo->GetRequestId());
1356
1357         r = __pTransferEvent->Fire(*(pTransferEventArg.release()));
1358         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to perform fire operation on ContentTransferEvent.", GetErrorMessage(r));
1359
1360         pTransferInfo->SetDownloadStatus(CONTENT_TRANSFER_STATUS_DOWNLOAD_COMPLETED);
1361
1362         return r;
1363 }
1364
1365 result
1366 _ContentTransferImpl::RemoveCompletedTransferInfo(ArrayList* pTransferInfoList)
1367 {
1368         ClearLastResult();
1369         std::unique_ptr<IEnumerator> pEnum;
1370         ContentTransferInfo* pTransferInfo = null;
1371         result r = E_SUCCESS;
1372
1373         if (pTransferInfoList == null)
1374         {
1375                 return r;
1376         }
1377
1378         pEnum = std::unique_ptr<IEnumerator>(pTransferInfoList->GetEnumeratorN());
1379         SysTryReturn(NID_CNT, pEnum != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
1380                                    "[E_OUT_OF_MEMORY] Failed to perform GetEnumeratorN operation.");
1381
1382         while (pEnum->MoveNext() == E_SUCCESS)
1383         {
1384                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
1385                 SysTryReturn(NID_CNT, pTransferInfo != null, r = E_INVALID_ARG, r,
1386                                    "[E_INVALID_ARG] ContentTransferInfo instance must not be null.");
1387
1388                 __pTransferInfoList->Remove(*pTransferInfo, true);
1389                 r = GetLastResult();
1390                 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] Failed to remove a item from transfer info list.", GetErrorMessage(r));
1391         }
1392
1393         return r;
1394 }
1395
1396 bool
1397 _ContentTransferImpl::ContentTransferHandler(void)
1398 {
1399         ClearLastResult();
1400         result r = E_SUCCESS;
1401         std::unique_ptr<IEnumerator> pEnum;
1402         std::unique_ptr<ArrayList> pDeleteList;
1403         ContentTransferInfo* pTransferInfo = null;
1404         ContentTransferStatus status = CONTENT_TRANSFER_STATUS_NONE;
1405         int downloadCount = 0;
1406         RequestId restRequestId = INVALID_REQUEST_ID;
1407         bool full = false;
1408         int idx = 0;
1409         bool check = false;
1410         int slot = 0;
1411         String destPath(L"");
1412         String sourcePath(L"");
1413
1414         pEnum = std::unique_ptr<IEnumerator>(__pTransferInfoList->GetEnumeratorN());
1415         if (pEnum == null)
1416         {
1417                 return false;
1418         }
1419
1420         while (pEnum->MoveNext() == E_SUCCESS)
1421         {
1422                 pTransferInfo = dynamic_cast<ContentTransferInfo*>(pEnum->GetCurrent());
1423                 SysTryReturn(NID_CNT, pTransferInfo != null, check, E_INVALID_ARG,
1424                                    "[E_INVALID_ARG] ContentTransferInfo instance must not be null.");
1425
1426                 status = pTransferInfo->GetContentTransferStatus();
1427
1428                 if (status == CONTENT_TRANSFER_STATUS_DOWNLOADING)
1429                 {
1430                         downloadCount++;
1431                         if (downloadCount == MAX_DOWNLOAD_COUNT)
1432                         {
1433                                 full = true;
1434                                 continue;
1435                         }
1436                         else
1437                         {
1438                                 continue;
1439                         }
1440                 }
1441                 else if (status == CONTENT_TRANSFER_STATUS_DOWNLOAD_READY)
1442                 {
1443                         if (full == true)
1444                         {
1445                                 StartTimer();
1446                                 r = GetLastResult();
1447                                 SysTryReturn(NID_CNT, !IsFailed(r), check, r, "[%s] Failed to perform StartTimer operation.", GetErrorMessage(r));
1448
1449                                 check = true;
1450                                 break;
1451                         }
1452
1453                         // get empty buffer slot from download buffer
1454                         // set slot information
1455                         r = SetDownloadSlotInfo(pTransferInfo, slot);
1456                         if (slot < 0)
1457                         {
1458                                 SysLogException(NID_CNT, r, "[%s] Failed to find an empty slot.", GetErrorMessage(r));
1459                                 check = true;
1460                                 break;
1461                         }
1462
1463                         if (IsFailed(r))
1464                         {
1465                                 SysLogException(NID_CNT, r, "[%s] Propagating.", GetErrorMessage(r));
1466                                 break;
1467                         }
1468
1469                         destPath = pTransferInfo->GetDestPath();
1470                         sourcePath = pTransferInfo->GetUri().ToString();
1471                         (__pContentDownloadHandlerSequence.get())[slot].SetSlot(slot);
1472
1473                         // request download
1474                         restRequestId = (__pContentDownloadHandlerSequence.get())[slot].HttpDownload(sourcePath,
1475                                         pTransferInfo->GetSourceFileSize(), destPath, &(__pContentDownloadUserDataSequence.get())[slot]);
1476                         r = GetLastResult();
1477                         SysTryLog(NID_CNT, restRequestId != INVALID_REQUEST_ID,
1478                                         "[%s] The rest request ID is invalid.", GetErrorMessage(r));
1479
1480                         if (IsFailed(r))
1481                         {
1482                                 r = RequestErrorEvent(r, pTransferInfo);
1483                                 SysTryReturn(NID_CNT, !IsFailed(r), check, E_INVALID_ARG,
1484                                                 "[E_INVALID_ARG] Failed to perform RequestErrorEvent operation.");
1485
1486                                 (__pContentDownloadUserDataSequence.get())[slot].SetSlotFlag(false);
1487
1488                                 continue;
1489                         }
1490
1491                         sourcePath = null;
1492                         destPath = null;
1493
1494                         pTransferInfo->SetRestRequestId(restRequestId);
1495                         pTransferInfo->SetDownloadStatus(CONTENT_TRANSFER_STATUS_DOWNLOADING);
1496                         downloadCount++;
1497
1498                         if (downloadCount == MAX_DOWNLOAD_COUNT)
1499                         {
1500                                 full = true;
1501                         }
1502                         else
1503                         {
1504                                 continue;
1505                         }
1506                 }
1507                 else if (status == CONTENT_TRANSFER_STATUS_DOWNLOAD_COMPLETED)
1508                 {
1509                         SetEmptySlotInternal();
1510
1511                         // TODO : should i check to sync
1512                         if (pDeleteList == null)
1513                         {
1514                                 pDeleteList = std::unique_ptr<ArrayList>(new (std::nothrow) ArrayList());
1515                                 SysTryReturn(NID_CNT, !IsFailed(r), check, E_OUT_OF_MEMORY,
1516                                                 "[E_OUT_OF_MEMORY] Failed to construct ArrayList.");
1517                         }
1518                         pDeleteList->Add(*pTransferInfo);
1519                 }
1520                 idx++;
1521         }
1522
1523         r = RemoveCompletedTransferInfo(pDeleteList.get());
1524         SysTryReturn(NID_CNT, !IsFailed(r), check, E_INVALID_ARG,
1525                         "[E_INVALID_ARG] Failed to remove the completed transfer info.");
1526
1527         return check;
1528 }
1529 }}