[content] Fix null check codes
[platform/framework/native/content.git] / src / FCnt_ContentDirectoryImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file                FCnt_ContentDirectoryImpl.cpp
19  * @brief               This is the implementation file for the %_ContentDirectoryImpl class.
20  *
21  * This file contains implementation of the %_ContentDirectoryImpl class.
22  */
23
24 #include <FBaseSysLog.h>
25 #include <FBaseInteger.h>
26 #include <FBaseLongLong.h>
27 #include <FBaseFloat.h>
28 #include <FBaseColIList.h>
29 #include <FBaseColIEnumeratorT.h>
30 #include <FCntContentDirectory.h>
31 #include <FCntContentSearchResult.h>
32 #include <FSysEnvironment.h>
33 #include <FBase_StringConverter.h>
34 #include <FCnt_ContentUtility.h>
35 #include <FCnt_ContentDirectoryImpl.h>
36
37 using namespace Tizen::Base;
38 using namespace Tizen::Base::Collection;
39 using namespace Tizen::Io;
40 using namespace Tizen::System;
41
42 namespace Tizen { namespace Content
43 {
44 // Declaration for Callback function registered to each media info details
45 bool MediaFoldersCb(media_folder_h folder, void* pUserdata);
46 // Declaration for Callback function registered to each media info details
47 bool MediaFolderItemsCb(media_info_h media, void* pUserdata);
48
49 _ContentDirectoryImpl::_ContentDirectoryImpl(void)
50         : Object()
51         , __pFilterHandle(null)
52         , __pFinalOutList(null)
53         , __contentType(CONTENT_TYPE_UNKNOWN)
54         , __isMultiContentType(false)
55         , __multiContentTypeExpr(L"")
56 {
57
58 }
59
60 // (disconnects the DB connection)
61 _ContentDirectoryImpl::~_ContentDirectoryImpl(void)
62 {
63         int ret = MEDIA_CONTENT_ERROR_NONE;
64         result r = E_SUCCESS;
65
66         ret = media_content_disconnect();
67         r = MapCoreErrorToNativeResult(ret);
68         SysTryLog(NID_CNT, r == E_SUCCESS, "[%s] Propagating for media_content_disconnect.", GetErrorMessage(r));
69
70         SysLog(NID_CNT, "media_content_disconnect result[%d].", ret);
71 }
72
73  _ContentDirectoryImpl*
74  _ContentDirectoryImpl::GetInstance(ContentDirectory& contentDirectory)
75 {
76         return (&contentDirectory != null) ? contentDirectory.__pImpl : null;
77 }
78
79 const _ContentDirectoryImpl*
80 _ContentDirectoryImpl::GetInstance(const ContentDirectory& contentDirectory)
81 {
82         return (&contentDirectory != null) ? contentDirectory.__pImpl : null;
83 }
84
85 //make a connection to DB
86 result
87 _ContentDirectoryImpl::Construct(ContentType type)
88 {
89         result r = E_SUCCESS;
90         int ret = MEDIA_CONTENT_ERROR_NONE;
91
92         ret = media_content_connect();
93         r = MapCoreErrorToNativeResult(ret);
94         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Propagating for media_content_connect.");
95
96         SysLog(NID_CNT, "media_content_connect result[%d].", ret);
97
98         __contentType = type;
99         __isMultiContentType = false;
100         __multiContentTypeExpr.Clear();
101
102         return  r;
103 }
104
105 //make a connection to DB
106 result
107 _ContentDirectoryImpl::Construct(const Tizen::Base::Collection::IListT<ContentType>& contentTypeList)
108 {
109         result r = E_SUCCESS;
110         int ret = MEDIA_CONTENT_ERROR_NONE;
111         ContentType     contentType = CONTENT_TYPE_UNKNOWN;
112
113         ret = media_content_connect();
114         r = MapCoreErrorToNativeResult(ret);
115         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Propagating for media_content_connect.");
116
117         SysLog(NID_CNT, "media_content_connect result[%d].", ret);
118
119         __multiContentTypeExpr.Clear();
120
121         std::unique_ptr<IEnumeratorT<ContentType> > pEnum(contentTypeList.GetEnumeratorN());
122
123         while ((pEnum.get() != NULL) && (pEnum->MoveNext() == E_SUCCESS))
124         {
125                 if (!__multiContentTypeExpr.IsEmpty())
126                 {
127                         r = __multiContentTypeExpr.Append("OR ");
128                         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
129                 }
130                 pEnum->GetCurrent(contentType);
131                 switch (contentType)
132                 {
133                         // Image-0,video-1,sound-2,music-3,other-4
134                 case CONTENT_TYPE_OTHER:
135                         r = __multiContentTypeExpr.Append("MEDIA_TYPE=4 ");
136                         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
137                         break;
138                 case CONTENT_TYPE_IMAGE:
139                         r = __multiContentTypeExpr.Append("MEDIA_TYPE=0 ");
140                         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
141                         break;
142                 case CONTENT_TYPE_AUDIO:
143                         r = __multiContentTypeExpr.Append("(MEDIA_TYPE=2 or MEDIA_TYPE=3) ");
144                         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");;
145                         break;
146                 case CONTENT_TYPE_VIDEO:
147                         r = __multiContentTypeExpr.Append("MEDIA_TYPE=1 ");
148                         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
149                         break;
150                 case CONTENT_TYPE_ALL:
151                         //If content type is CONTENT_TYPE_ALL, then MEDIA_TYPE is empty
152                         break;
153                 default:
154                         break;
155                 }
156         }
157
158         r = __multiContentTypeExpr.Insert('(', 0);
159         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
160
161         r = __multiContentTypeExpr.Insert(')', __multiContentTypeExpr.GetLength());
162         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
163
164         __isMultiContentType = true;
165
166         return  r;
167 }
168
169 result
170 _ContentDirectoryImpl::CreateFolderFilter(bool isMultiContentType, const Tizen::Base::String& inputFolderPath) const
171 {
172         result r = E_SUCCESS;
173         std::unique_ptr<filter_h, FilterHandleDeleter> pFilterHandle(new (std::nothrow) filter_h);
174         int ret = MEDIA_CONTENT_ERROR_NONE;
175         String inputCondition = L"";
176         String folderPath(inputFolderPath);
177
178         ret = media_filter_create(pFilterHandle.get());
179         r = MapCoreErrorToNativeResult(ret);
180         SysTryReturnResult(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, r, "Failed to perform media_filter_create operation.");
181
182         if (isMultiContentType)
183         {
184                 r = inputCondition.Append(__multiContentTypeExpr);
185                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
186         }
187         else
188         {
189                 switch (__contentType)
190                 {
191                         // Image-0,video-1,sound-2,music-3,other-4
192                 case CONTENT_TYPE_OTHER:
193                         inputCondition = "MEDIA_TYPE=4 ";
194                         break;
195                 case CONTENT_TYPE_IMAGE:
196                         inputCondition = "MEDIA_TYPE=0 ";
197                         break;
198                 case CONTENT_TYPE_AUDIO:
199                         inputCondition = "(MEDIA_TYPE=2 or MEDIA_TYPE=3) ";
200                         break;
201                 case CONTENT_TYPE_VIDEO:
202                         inputCondition = "MEDIA_TYPE=1 ";
203                         break;
204                 case CONTENT_TYPE_ALL:
205                         //If content type is CONTENT_TYPE_ALL, then MEDIA_TYPE is empty
206                         break;
207                 default:
208                         break;
209                 }
210         }
211
212         if (!folderPath.IsEmpty())
213         {
214                 if (!inputCondition.IsEmpty()) //For CONTENT_TYPE_ALL inputCondition is empty
215                 {
216                         r = inputCondition.Append("AND FOLDER_PATH = ");
217                         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
218                 }
219                 else
220                 {
221                         r = inputCondition.Append("FOLDER_PATH = ");
222                         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
223                 }
224
225                 r = folderPath.Insert('"', 0);
226                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Insert operation.");
227                 r = folderPath.Insert('"', folderPath.GetLength());
228                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Insert operation.");
229
230                 r = inputCondition.Append(folderPath);
231                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
232         }
233
234         if (!inputCondition.IsEmpty())
235         {
236                 //CopyToCharArrayN: utility function, converts a osp string to char*
237                 std::unique_ptr<char[]> pInputCond(_StringConverter::CopyToCharArrayN(inputCondition));
238                 SysTryReturnResult(NID_CNT, pInputCond, E_OUT_OF_MEMORY, "The memory is insufficient.");
239
240                 SysLog(NID_CNT, "pInputCond is [%s].", pInputCond.get());
241
242                 ret = media_filter_set_condition(*(pFilterHandle.get()), pInputCond.get(), MEDIA_CONTENT_COLLATE_DEFAULT);
243                 r = MapCoreErrorToNativeResult(ret);
244                 SysTryReturnResult(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, r, "Failed to perform media_filter_set_condition operation.");
245         }
246
247         __pFilterHandle.reset(pFilterHandle.release());
248
249         return  r;
250 }
251
252 int
253 _ContentDirectoryImpl::GetContentDirectoryCount(void) const
254 {
255         int directoryCount = 0;
256         result r = E_SUCCESS;
257         int ret = MEDIA_CONTENT_ERROR_NONE;
258
259         r = CreateFolderFilter(__isMultiContentType, L"");
260         SysTryReturnResult(NID_CNT, !IsFailed(r), E_SYSTEM, "Propagating for CreateFolderFilter.");
261
262         ret = media_folder_get_folder_count_from_db(*(__pFilterHandle.get()), &directoryCount);
263         r = MapCoreErrorToNativeResult(ret);
264         SysTryReturnResult(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, r, "Failed to perform media_folder_get_folder_count_from_db operation.");
265
266         SysLog(NID_CNT, "directoryCount is [%d].", directoryCount);
267
268         SetLastResult(r);
269         return directoryCount;
270 }
271
272 IList*
273 _ContentDirectoryImpl::GetContentDirectoryPathListN(Tizen::Base::SortOrder sortOrder) const
274 {
275         result r = E_SUCCESS;
276         int ret = MEDIA_CONTENT_ERROR_NONE;
277         std::unique_ptr<GList, GListDeleter> pItemList;
278         GList* pTempList = null;
279         std::unique_ptr<char> pFolderPath;
280         char* pTempFolderPath = null;
281         std::unique_ptr<media_folder_s, FolderHandleDeleter> pFolderHandle;
282         std::unique_ptr<Object> pValue;
283
284         __pFinalOutList = std::unique_ptr<ArrayList, AllElementsDeleter>(new (std::nothrow) ArrayList());
285         SysTryReturn(NID_CNT, __pFinalOutList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] FinalOutList is null.");
286
287         r = __pFinalOutList->Construct();
288         SysTryReturn(NID_CNT, r == E_SUCCESS, null, r, "[%s] Failed to construct __pFinalOutList ArrayList.", GetErrorMessage(r));
289
290         r = CreateFolderFilter(__isMultiContentType, L"");
291         SysTryReturn(NID_CNT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
292
293         if (sortOrder == SORT_ORDER_ASCENDING)
294         {
295                 ret = media_filter_set_order(*(__pFilterHandle.get()), MEDIA_CONTENT_ORDER_ASC, MEDIA_PATH, MEDIA_CONTENT_COLLATE_DEFAULT);
296                 r = MapCoreErrorToNativeResult(ret);
297                 SysTryReturn(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, null, r,
298                                 "[%s] Failed to perform media_filter_set_order operation.", GetErrorMessage(r));
299         }
300         else if (sortOrder == SORT_ORDER_DESCENDING)
301         {
302                 ret = media_filter_set_order(*(__pFilterHandle.get()), MEDIA_CONTENT_ORDER_DESC, MEDIA_PATH, MEDIA_CONTENT_COLLATE_DEFAULT);
303                 r = MapCoreErrorToNativeResult(ret);
304                 SysTryReturn(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, null, r,
305                                 "[%s] Failed to perform media_filter_set_order operation.", GetErrorMessage(r));
306         }
307
308         pTempList = pItemList.get();
309         ret = media_folder_foreach_folder_from_db(*(__pFilterHandle.get()), MediaFoldersCb, &pTempList);
310         r = MapCoreErrorToNativeResult(ret);
311         SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform media_folder_foreach_folder_from_db operation.", GetErrorMessage(r));
312
313         SysTryReturn(NID_CNT, pTempList != NULL, null, r, "[%s] pItemList for media_folder_foreach_folder_from_db is null.", GetErrorMessage(r));
314
315         for (int idx = 0; idx < (int)g_list_length(pTempList); idx++)
316         {
317                 pFolderHandle.reset(static_cast<media_folder_h>(g_list_nth_data(pTempList, idx)));
318
319                 if (pFolderHandle.get() != NULL)
320                 {
321                         pTempFolderPath = pFolderPath.get();
322                         ret = media_folder_get_path(pFolderHandle.get(), &pTempFolderPath);
323                         r = MapCoreErrorToNativeResult(ret);
324                         SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform media_folder_get_path operation.", GetErrorMessage(r));
325
326                         if (pTempFolderPath != NULL)
327                         {
328                                 SysLog(NID_CNT, "pFolderPath is [%s].", pTempFolderPath);
329
330                                 pValue = std::unique_ptr<Object>(new (std::nothrow) String(pTempFolderPath));
331                         }
332                         if (pValue != NULL)
333                         {
334                                 r = __pFinalOutList->Add(*(pValue.release()));
335                                 SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform Add operation to __pFinalOutList.", GetErrorMessage(r));
336                         }
337                 }
338         }
339
340         SetLastResult(r);
341         return __pFinalOutList.release();
342 }
343
344 int
345 _ContentDirectoryImpl::GetContentDirectoryItemCount(const Tizen::Base::String& contentDirectoryPath) const
346 {
347         SysLog(NID_CNT, "contentDirectoryPath is [%ls]", contentDirectoryPath.GetPointer());
348
349         int directoryItemCount = 0;
350         result r = E_SUCCESS;
351         int ret = MEDIA_CONTENT_ERROR_NONE;
352         GList* pItemList = NULL;
353         std::unique_ptr<char> pFolderId;
354         char* pTempFolderId = null;
355         std::unique_ptr<media_folder_s, FolderHandleDeleter> pFolderHandle;
356
357         SysTryReturn(NID_CNT, CheckMediaPath(contentDirectoryPath), directoryItemCount, E_INVALID_ARG,
358                         "[E_INVALID_ARG] Failed to perform CheckMediaPath operation.");
359
360         String detachedPath = contentDirectoryPath;
361
362         if (contentDirectoryPath.EndsWith(L"/"))
363         {
364                 r = detachedPath.Remove(detachedPath.GetLength() - 1, 1);
365                 SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, E_INVALID_ARG, "[E_INVALID_ARG] Failed to remove the path string.");
366         }
367
368         r = CreateFolderFilter(__isMultiContentType, detachedPath);
369         SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
370
371         ret = media_folder_foreach_folder_from_db(*(__pFilterHandle.get()), MediaFoldersCb, &pItemList);
372         r = MapCoreErrorToNativeResult(ret);
373         SysTryReturn(NID_CNT, r == E_SUCCESS, directoryItemCount, r,
374                         "[%s] Failed to perform media_folder_foreach_folder_from_db operation.", GetErrorMessage(r));
375
376         SysTryReturn(NID_CNT, pItemList != NULL, directoryItemCount, r,
377                         "[%s] pItemList for media_folder_foreach_folder_from_db is null.", GetErrorMessage(r));
378
379         for (int idx = 0; idx < (int)g_list_length(pItemList); idx++)
380         {
381                 SysLog(NID_CNT, "idx is [%d] and (int)g_list_length(pItemList) is [%d].", idx, (int)g_list_length(pItemList));
382
383                 pFolderHandle.reset(static_cast<media_folder_h>(g_list_nth_data(pItemList, idx)));
384
385                 if (pFolderHandle.get() != NULL)
386                 {
387                         pTempFolderId = pFolderId.get();
388                         ret = media_folder_get_folder_id(pFolderHandle.get(), &pTempFolderId);
389                         r = MapCoreErrorToNativeResult(ret);
390                         SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, r,
391                                         "[%s] Failed to perform media_folder_get_folder_id operation.", GetErrorMessage(r));
392                 }
393                 else
394                 {
395                         r = E_SYSTEM;
396                         SysTryReturn(NID_CNT, r != E_SUCCESS, directoryItemCount, r, "[E_SYSTEM] pFolderHandle is null.");
397                 }
398         }
399
400         if (pTempFolderId != NULL)
401         {
402                 r = CreateFolderFilter(__isMultiContentType, L"");
403                 SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
404
405                 ret = media_folder_get_media_count_from_db(pTempFolderId, *(__pFilterHandle.get()), &directoryItemCount);
406                 r = MapCoreErrorToNativeResult(ret);
407                 SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, r,
408                                 "[%s] Failed to perform media_folder_get_media_count_from_db operation.", GetErrorMessage(r));
409         }
410
411         SysLog(NID_CNT, "directoryItemCount is [%d].", directoryItemCount);
412
413         SetLastResult(r);
414         return directoryItemCount;
415 }
416
417 // Osp column names are mapped with slp column names
418 // CONTENT_TYPE_OTHER and CONTENT_TYPE_IMAGE (0 - 13 ) are valid columns
419 // CONTENT_TYPE_VIDEO  (0 - 16 ) are valid columns
420 // CONTENT_TYPE_ALL and  CONTENT_TYPE_VIDEO (0 - 18 ) are valid columns
421 // if the given osp column is out of the specified range of the type, E_INVALID_ARG is retuned.
422 result
423 _ContentDirectoryImpl::GetSlpColumnName(String& inputCol, String sortCol) const
424 {
425         String          ospColumnName(L"");
426         String          slpColumnName(L"");
427         String          columnName(sortCol);
428         result          r = E_SUCCESS;
429         int             maxCols = MAX_QUERY_COLUMNS;
430         
431         if(!__isMultiContentType)
432         {
433                 switch (__contentType)
434                 {
435                 case CONTENT_TYPE_OTHER:
436                         //fall through
437                 case CONTENT_TYPE_IMAGE:
438                         maxCols = MAX_QUERY_COLUMNS_FOR_IMAGE_OTHERS;
439                         break;
440                 case CONTENT_TYPE_VIDEO:
441                         maxCols = MAX_QUERY_COLUMNS_FOR_VIDEO;
442                         break;
443                 case CONTENT_TYPE_AUDIO:
444                         //fall through
445                 case CONTENT_TYPE_ALL:
446                         maxCols = MAX_QUERY_COLUMNS;
447                         break;
448                 default:
449                         break;
450                 }
451         }
452         else
453         {
454                 if(!__multiContentTypeExpr.IsEmpty())
455                 {
456                         if(__multiContentTypeExpr.Contains("MEDIA_TYPE=2"))
457                         {
458                                 maxCols = MAX_QUERY_COLUMNS;
459                         }
460                         else if(__multiContentTypeExpr.Contains("MEDIA_TYPE=1"))
461                         {
462                                 maxCols = MAX_QUERY_COLUMNS_FOR_VIDEO;
463                         }
464                         else if(__multiContentTypeExpr.Contains("MEDIA_TYPE=0"))
465                         {
466                                 maxCols = MAX_QUERY_COLUMNS_FOR_IMAGE_OTHERS;
467                         }
468                 }
469         }
470
471         for (int colIndex=0; colIndex < maxCols; colIndex++)
472         {
473                 ospColumnName.Clear();
474                 slpColumnName.Clear();
475
476                 ospColumnName = dbfieldinfo[colIndex].dbFieldOspName ;
477                 slpColumnName = dbfieldinfo[colIndex].dbFieldSlpName ;
478
479                 ospColumnName.ToUpper();
480                 columnName.ToUpper();
481
482                 if (columnName == ospColumnName)
483                 {
484                         inputCol = slpColumnName;
485                         return r;
486                 }
487         }
488         return E_INVALID_ARG;
489 }
490
491 IList*
492 _ContentDirectoryImpl::GetContentDirectoryItemListN(const Tizen::Base::String& contentDirectoryPath, int pageNo, int countPerPage,
493                                                     const Tizen::Base::String& column, Tizen::Base::SortOrder sortOrder) const
494 {
495         SysLog(NID_CNT, "contentDirectoryPath is [%ls].", contentDirectoryPath.GetPointer());
496
497         result r = E_SUCCESS;
498         int totalCount = 0;
499         int totalPageCount = 0;
500         int ret = MEDIA_CONTENT_ERROR_NONE;
501         String slpColumn = L"";
502         std::unique_ptr<GList, GListDeleter> pItemList;
503         GList* pTempList = null;
504         std::unique_ptr<char> pFolderId;
505         char* pTempFolderId = null;
506         std::unique_ptr<media_folder_s, FolderHandleDeleter> pFolderHandle;
507         int offset = 0;
508
509         SysTryReturn(NID_CNT, CheckMediaPath(contentDirectoryPath), null, E_INVALID_ARG,
510                         "[E_INVALID_ARG] Failed to perform CheckMediaPath operation.");
511
512         String detachedPath = contentDirectoryPath;
513
514         if (contentDirectoryPath.EndsWith(L"/"))
515         {
516                 r = detachedPath.Remove(detachedPath.GetLength() - 1, 1);
517                 SysTryReturn(NID_CNT, !IsFailed(r), null, E_INVALID_ARG, "[E_INVALID_ARG] Failed to remove the path string.");
518         }
519
520         __pFinalOutList = std::unique_ptr<ArrayList, AllElementsDeleter>(new (std::nothrow) ArrayList());
521         SysTryReturn(NID_CNT, __pFinalOutList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] FinalOutList is null.");
522
523         r = __pFinalOutList->Construct();
524         SysTryReturn(NID_CNT, r == E_SUCCESS, null, r, "[%s] Failed to construct __pFinalOutList ArrayList.", GetErrorMessage(r));
525
526         r = CreateFolderFilter(__isMultiContentType, detachedPath);
527         SysTryReturn(NID_CNT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
528
529         if ((!column.IsEmpty()) && (sortOrder != SORT_ORDER_NONE))
530         {
531                 //__inputColumnName (osp column name) is replaced with slpColumn (slp column name).
532                 r = GetSlpColumnName(slpColumn, column);
533                 SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform GetSlpColumnName operation.", GetErrorMessage(r));
534
535                 //CopyToCharArrayN: utility function, converts a osp string to char*
536                 std::unique_ptr<char[]> pSortCol(_StringConverter::CopyToCharArrayN(slpColumn));
537                 SysTryReturn(NID_CNT, pSortCol, null, E_OUT_OF_MEMORY, "The memory is insufficient.");
538
539                 if (sortOrder == SORT_ORDER_ASCENDING)
540                 {
541                         ret = media_filter_set_order(*(__pFilterHandle.get()), MEDIA_CONTENT_ORDER_ASC, pSortCol.get(), MEDIA_CONTENT_COLLATE_DEFAULT);
542                         r = MapCoreErrorToNativeResult(ret);
543                         SysTryReturn(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, null, r,
544                                         "[%s] Failed to perform media_filter_set_order operation.", GetErrorMessage(r));
545                 }
546                 else if (sortOrder == SORT_ORDER_DESCENDING)
547                 {
548                         ret = media_filter_set_order(*(__pFilterHandle.get()), MEDIA_CONTENT_ORDER_DESC, pSortCol.get(), MEDIA_CONTENT_COLLATE_DEFAULT);
549                         r = MapCoreErrorToNativeResult(ret);
550                         SysTryReturn(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, null, r,
551                                         "[%s] Failed to perform media_filter_set_order operation.", GetErrorMessage(r));
552                 }
553         }
554
555         pTempList = pItemList.get();
556         ret = media_folder_foreach_folder_from_db(*(__pFilterHandle.get()), MediaFoldersCb, &pTempList);
557         r = MapCoreErrorToNativeResult(ret);
558         SysTryReturn(NID_CNT, !IsFailed(r), null, r,
559                         "[%s] Failed to perform media_folder_foreach_folder_from_db operation.", GetErrorMessage(r));
560
561         if (pTempList != NULL)
562         {
563                 for (int idx = 0; idx < (int)g_list_length(pTempList); idx++)
564                 {
565                         SysLog(NID_CNT, "idx is [%d] and (int)g_list_length(pItemList) is [%d].", idx, (int)g_list_length(pTempList));
566
567                         pFolderHandle.reset(static_cast<media_folder_h>(g_list_nth_data(pTempList, idx)));
568
569                         if (pFolderHandle.get() != NULL)
570                         {
571                                 pTempFolderId = pFolderId.get();
572                                 ret = media_folder_get_folder_id(pFolderHandle.get(), &pTempFolderId);
573                                 r = MapCoreErrorToNativeResult(ret);
574                                 SysTryReturn(NID_CNT, !IsFailed(r), null, r,
575                                                 "[%s] Failed to perform media_folder_get_folder_id operation.", GetErrorMessage(r));
576                         }
577                         else
578                         {
579                                 r = E_SYSTEM;
580                                 SysTryReturn(NID_CNT, r != E_SUCCESS, null, r, "[E_SYSTEM] pFolderHandle is null.");
581                         }
582                 }
583         }
584
585         if (pTempFolderId != NULL)
586         {
587                 r = CreateFolderFilter(__isMultiContentType, L"");
588                 SysTryReturn(NID_CNT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
589
590                 ret = media_folder_get_media_count_from_db(pTempFolderId, *(__pFilterHandle.get()), &totalCount);
591                 r = MapCoreErrorToNativeResult(ret);
592                 SysTryReturn(NID_CNT, !IsFailed(r), null, r,
593                                 "[%s] Failed to perform media_folder_get_media_count_from_db operation.", GetErrorMessage(r));
594
595                 SysLog(NID_CNT, "totalCount is [%d].", totalCount);
596         }
597
598         if (totalCount > 0)
599         {
600                 if ((totalCount % countPerPage) == 0)
601                 {
602                         totalPageCount = totalCount / countPerPage;
603                 }
604                 else
605                 {
606                         totalPageCount = (totalCount / countPerPage) + 1;
607                 }
608
609                 SysTryReturn(NID_CNT, ((pageNo >= 1) && (pageNo <= totalPageCount)) , NULL, E_INVALID_ARG, "[E_INVALID_ARG] (pageNo < 1) || (pageNo > totalPageCount).");
610
611                 offset = (pageNo * countPerPage) - countPerPage;
612
613                 SysLog(NID_CNT, "totalCount [%d] totalPageCount[%d] __countPerPage[%d] __pageNo[%d] offset[%d]",
614                                 totalCount, totalPageCount, countPerPage, pageNo, offset);
615
616                 ret = media_filter_set_offset(*(__pFilterHandle.get()),offset,countPerPage);
617                 r = MapCoreErrorToNativeResult(ret);
618                 SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform media_filter_set_offset operation.", GetErrorMessage(r));
619
620                 r = FillFinalOutList(pTempFolderId);
621                 SysTryReturn(NID_CNT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to perform FillFinalOutList operation.");
622         }
623         else if (pageNo > 1)
624         {
625                 r = E_INVALID_ARG;
626                 SysTryReturn(NID_CNT, !(IsFailed(r)), null, r, "[E_INVALID_ARG] (pageNo > 1) and (totalcount = 0).");
627         }
628         
629         SetLastResult(r);
630         return __pFinalOutList.release();
631 }
632
633 result
634 _ContentDirectoryImpl::FillFinalOutList(char* pFolderId) const
635 {
636         int ret = MEDIA_CONTENT_ERROR_NONE;
637         result r = E_SUCCESS;
638         std::unique_ptr<GList, GListDeleter> pItemList;
639         GList* pTempList = NULL;
640         std::unique_ptr<media_info_s, MediaHandleDeleter> pMediaHandle;
641
642         ContentInfo::_ContentData*                      pContentData = null;
643         ImageContentInfo::_ImageContentData*            pImageContentData = null;
644         AudioContentInfo::_AudioContentData*            pAudioContentData = null;
645         VideoContentInfo::_VideoContentData*            pVideoContentData = null;
646
647         std::unique_ptr<ImageContentInfo> pImageContentInfo;
648         std::unique_ptr<AudioContentInfo> pAudioContentInfo;
649         std::unique_ptr<VideoContentInfo> pVideoContentInfo;
650         std::unique_ptr<OtherContentInfo> pOtherContentInfo;
651
652         pTempList = pItemList.get();
653         ret = media_folder_foreach_media_from_db(pFolderId, *(__pFilterHandle.get()), MediaFolderItemsCb, &pTempList);
654         r = MapCoreErrorToNativeResult(ret);
655         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform media_folder_foreach_media_from_db operation.");
656
657         SysTryReturnResult(NID_CNT, pTempList != NULL, r, "pItemList for media_info_foreach_media_from_db is null.");
658
659         media_content_type_e mediaType;
660
661         for (int idx = 0; idx < (int)g_list_length(pTempList); idx++)
662         {
663                 pMediaHandle.reset(static_cast<media_info_h>(g_list_nth_data(pTempList, idx)));
664
665                 ret = media_info_get_media_type(pMediaHandle.get(), &mediaType);
666                 r = MapCoreErrorToNativeResult(ret);
667                 SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform media_info_get_media_type operation.");
668
669                 switch (mediaType)
670                 {
671                 case MEDIA_CONTENT_TYPE_OTHERS:
672                         pOtherContentInfo = std::unique_ptr<OtherContentInfo>(new (std::nothrow) OtherContentInfo);
673                         SysTryReturnResult(NID_CNT, pOtherContentInfo.get() != null, E_OUT_OF_MEMORY, "Failed to create pOtherContentInfo.");
674
675                         pContentData = pOtherContentInfo->GetContentData();
676                         SysTryReturnResult(NID_CNT, pContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
677
678                         r = _ContentUtility::FillContentData(pMediaHandle.get(), pContentData);
679                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillContentData operation.");
680
681                         // Shallow copy, adds just the pointer: not the element
682                         r = __pFinalOutList->Add(*(pOtherContentInfo.release()));
683                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform Add operation to pFinalOutList.");
684
685                         break;
686                 case MEDIA_CONTENT_TYPE_IMAGE:
687                         pImageContentInfo = std::unique_ptr<ImageContentInfo>(new (std::nothrow) ImageContentInfo);
688                         SysTryReturnResult(NID_CNT, pImageContentInfo.get() != null, E_OUT_OF_MEMORY, "Failed to create pImageContentInfo.");
689
690                         pContentData = pImageContentInfo->GetContentData();
691                         SysTryReturnResult(NID_CNT, pContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
692
693                         pImageContentData = pImageContentInfo->GetImageContentData();
694                         SysTryReturnResult(NID_CNT, pImageContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
695
696                         r = _ContentUtility::FillContentData(pMediaHandle.get(), pContentData);
697                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillContentData operation.");
698
699                         r = _ContentUtility::FillImageContentData(pMediaHandle.get(), pImageContentData);
700                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform GetDataFromImageTable operation.");
701
702                         // Shallow copy, adds just the pointer: not the element
703                         r = __pFinalOutList->Add(*(pImageContentInfo.release()));
704                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform Add operation to __pFinalOutList.");
705
706                         break;
707                 case MEDIA_CONTENT_TYPE_MUSIC:
708                         //fall through
709                 case MEDIA_CONTENT_TYPE_SOUND:
710                         pAudioContentInfo = std::unique_ptr<AudioContentInfo>(new (std::nothrow) AudioContentInfo);
711                         SysTryReturnResult(NID_CNT, pAudioContentInfo.get() != null, E_OUT_OF_MEMORY, "Failed to create pAudioContentInfo.");
712
713                         pContentData = pAudioContentInfo->GetContentData();
714                         SysTryReturnResult(NID_CNT, pContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
715
716                         pAudioContentData = pAudioContentInfo->GetAudioContentData();
717                         SysTryReturnResult(NID_CNT, pAudioContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
718
719                         r = _ContentUtility::FillContentData(pMediaHandle.get(), pContentData);
720                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillContentData operation.");
721
722                         r = _ContentUtility::FillAudioContentData(pMediaHandle.get(), pAudioContentData);
723                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillAudioContentData operation.");
724
725                         // Shallow copy, adds just the pointer: not the element
726                         r = __pFinalOutList->Add(*(pAudioContentInfo.release()));
727                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform Add operation to __pFinalOutList.");
728
729                         break;
730                 case MEDIA_CONTENT_TYPE_VIDEO:
731                         pVideoContentInfo = std::unique_ptr<VideoContentInfo>(new (std::nothrow) VideoContentInfo);
732                         SysTryReturnResult(NID_CNT, pVideoContentInfo.get() != null, E_OUT_OF_MEMORY, "Failed to create pVideoContentInfo.");
733
734                         pContentData = pVideoContentInfo->GetContentData();
735                         SysTryReturnResult(NID_CNT, pContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
736
737                         pVideoContentData = pVideoContentInfo->GetVideoContentData();
738                         SysTryReturnResult(NID_CNT, pVideoContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
739
740                         r = _ContentUtility::FillContentData(pMediaHandle.get(), pContentData);
741                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillContentData operation.");
742
743                         r = _ContentUtility::FillVideoContentData(pMediaHandle.get(), pVideoContentData);
744                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillVideoContentData operation.");
745
746                         // Shallow copy, adds just the pointer: not the element
747                         r = __pFinalOutList->Add(*(pVideoContentInfo.release()));
748                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform Add operation to __pFinalOutList.");
749
750                         break;
751                 default:
752                         break;
753                 }
754         }
755
756         return r;
757 }
758
759 bool
760 _ContentDirectoryImpl::CheckMediaPath(const Tizen::Base::String& directoryPath) const
761 {
762         String phoneStr = Environment::GetMediaPath();
763         String mmcStr = Environment::GetExternalStoragePath();
764
765         if (!(directoryPath.StartsWith(phoneStr, 0) || directoryPath.StartsWith(mmcStr , 0)))
766         {
767                 String checkPhone;
768                 result r = phoneStr.SubString(0, (phoneStr.GetLength() - 1), checkPhone);
769                 SysTryReturn(NID_CNT, !IsFailed(r), false, E_INVALID_ARG, "[E_INVALID_ARG] Failed to substring operation.");
770
771                 String checkMmc;
772                 r = mmcStr.SubString(0, (mmcStr.GetLength() - 1), checkMmc);
773                 SysTryReturn(NID_CNT, !IsFailed(r), false, E_INVALID_ARG, "[E_INVALID_ARG] Failed to substring operation.");
774
775                 SysTryReturn(NID_CNT, (directoryPath.Equals(checkPhone) || directoryPath.Equals(checkMmc)), false, E_INVALID_ARG,
776                                 "[E_INVALID_ARG] The contentDirectoryPath is not valid[%ls].", directoryPath.GetPointer());
777         }
778
779         return true;
780 }
781
782 result
783 _ContentDirectoryImpl::MapCoreErrorToNativeResult(int reason) const
784 {
785         result r = E_SUCCESS;
786
787         switch (reason)
788         {
789         case MEDIA_CONTENT_ERROR_NONE:
790                 r = E_SUCCESS;
791                 break;
792
793         case MEDIA_CONTENT_ERROR_DB_BUSY:
794                 r = E_SERVICE_BUSY;
795                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_DB_BUSY");
796                 break;
797
798         case MEDIA_CONTENT_ERROR_DB_FAILED:
799                 r = E_SYSTEM;
800                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_DB_FAILED");
801                 break;
802
803         case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY:
804                 r = E_OUT_OF_MEMORY;
805                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_OUT_OF_MEMORY");
806                 break;
807
808         default:
809                 SysLog(NID_CNT, "default");
810                 r = E_SYSTEM;
811                 break;
812         }
813         return r;
814 }
815
816 // Callback function registered to each media info details
817 // all items are appended to the list
818 bool
819 MediaFoldersCb(media_folder_h folder, void* pUserdata)
820 {
821         int ret  = MEDIA_CONTENT_ERROR_NONE;
822         media_folder_h new_folder = NULL;
823         ret = media_folder_clone(&new_folder, folder);
824         SysTryLog(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, "[E_SYSTEM] Propagating for media_folder_clone.");
825
826         GList** pList = (GList**)pUserdata;
827         *pList = g_list_append(*pList, new_folder);
828
829         return true;
830 }
831
832 // Callback function registered to each media info details
833 // all items are appended to the list
834 bool
835 MediaFolderItemsCb(media_info_h media, void* pUserdata)
836 {
837         int ret  = MEDIA_CONTENT_ERROR_NONE;
838         media_info_h new_media = NULL;
839         ret = media_info_clone(&new_media, media);
840         SysTryLog(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, "[E_SYSTEM] Propagating for media_info_clone.");
841
842         GList** pList = (GList**)pUserdata;
843         *pList = g_list_append(*pList, new_media);
844
845         return true;
846 }
847
848 }}