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