[content] Fix bug on ContentDirectory
[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.Replace("\'", "''");
226                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Replace operation for nameExpr.");
227
228                 r = folderPath.Insert('\'', 0);
229                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Insert operation for nameExpr.");
230
231                 r = folderPath.Insert('\'', folderPath.GetLength());
232                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Insert operation for nameExpr.");
233
234                 r = inputCondition.Append(folderPath);
235                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation.");
236         }
237
238         if (!inputCondition.IsEmpty())
239         {
240                 //CopyToCharArrayN: utility function, converts a osp string to char*
241                 std::unique_ptr<char[]> pInputCond(_StringConverter::CopyToCharArrayN(inputCondition));
242                 SysTryReturnResult(NID_CNT, pInputCond, E_OUT_OF_MEMORY, "The memory is insufficient.");
243
244                 SysLog(NID_CNT, "pInputCond is [%s].", pInputCond.get());
245
246                 ret = media_filter_set_condition(*(pFilterHandle.get()), pInputCond.get(), MEDIA_CONTENT_COLLATE_DEFAULT);
247                 r = MapCoreErrorToNativeResult(ret);
248                 SysTryReturnResult(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, r, "Failed to perform media_filter_set_condition operation.");
249         }
250
251         __pFilterHandle.reset(pFilterHandle.release());
252
253         return  r;
254 }
255
256 int
257 _ContentDirectoryImpl::GetContentDirectoryCount(void) const
258 {
259         int directoryCount = 0;
260         result r = E_SUCCESS;
261         int ret = MEDIA_CONTENT_ERROR_NONE;
262
263         r = CreateFolderFilter(__isMultiContentType, L"");
264         SysTryReturnResult(NID_CNT, !IsFailed(r), E_SYSTEM, "Propagating for CreateFolderFilter.");
265
266         ret = media_folder_get_folder_count_from_db(*(__pFilterHandle.get()), &directoryCount);
267         r = MapCoreErrorToNativeResult(ret);
268         SysTryReturnResult(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, r, "Failed to perform media_folder_get_folder_count_from_db operation.");
269
270         SysLog(NID_CNT, "directoryCount is [%d].", directoryCount);
271
272         SetLastResult(r);
273         return directoryCount;
274 }
275
276 IList*
277 _ContentDirectoryImpl::GetContentDirectoryPathListN(Tizen::Base::SortOrder sortOrder) const
278 {
279         result r = E_SUCCESS;
280         int ret = MEDIA_CONTENT_ERROR_NONE;
281         std::unique_ptr<GList, GListDeleter> pItemList;
282         GList* pTempList = null;
283         std::unique_ptr<char> pFolderPath;
284         char* pTempFolderPath = null;
285         std::unique_ptr<media_folder_s, FolderHandleDeleter> pFolderHandle;
286         std::unique_ptr<Object> pValue;
287
288         __pFinalOutList = std::unique_ptr<ArrayList, AllElementsDeleter>(new (std::nothrow) ArrayList());
289         SysTryReturn(NID_CNT, __pFinalOutList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] FinalOutList is null.");
290
291         r = __pFinalOutList->Construct();
292         SysTryReturn(NID_CNT, r == E_SUCCESS, null, r, "[%s] Failed to construct __pFinalOutList ArrayList.", GetErrorMessage(r));
293
294         r = CreateFolderFilter(__isMultiContentType, L"");
295         SysTryReturn(NID_CNT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
296
297         if (sortOrder == SORT_ORDER_ASCENDING)
298         {
299                 ret = media_filter_set_order(*(__pFilterHandle.get()), MEDIA_CONTENT_ORDER_ASC, MEDIA_PATH, MEDIA_CONTENT_COLLATE_DEFAULT);
300                 r = MapCoreErrorToNativeResult(ret);
301                 SysTryReturn(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, null, r,
302                                 "[%s] Failed to perform media_filter_set_order operation.", GetErrorMessage(r));
303         }
304         else if (sortOrder == SORT_ORDER_DESCENDING)
305         {
306                 ret = media_filter_set_order(*(__pFilterHandle.get()), MEDIA_CONTENT_ORDER_DESC, MEDIA_PATH, MEDIA_CONTENT_COLLATE_DEFAULT);
307                 r = MapCoreErrorToNativeResult(ret);
308                 SysTryReturn(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, null, r,
309                                 "[%s] Failed to perform media_filter_set_order operation.", GetErrorMessage(r));
310         }
311
312         pTempList = pItemList.get();
313         ret = media_folder_foreach_folder_from_db(*(__pFilterHandle.get()), MediaFoldersCb, &pTempList);
314         r = MapCoreErrorToNativeResult(ret);
315         SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform media_folder_foreach_folder_from_db operation.", GetErrorMessage(r));
316
317         SysTryReturn(NID_CNT, pTempList != NULL, null, r, "[%s] pItemList for media_folder_foreach_folder_from_db is null.", GetErrorMessage(r));
318
319         for (int idx = 0; idx < (int)g_list_length(pTempList); idx++)
320         {
321                 pFolderHandle.reset(static_cast<media_folder_h>(g_list_nth_data(pTempList, idx)));
322
323                 if (pFolderHandle.get() != NULL)
324                 {
325                         pTempFolderPath = pFolderPath.get();
326                         ret = media_folder_get_path(pFolderHandle.get(), &pTempFolderPath);
327                         r = MapCoreErrorToNativeResult(ret);
328                         SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform media_folder_get_path operation.", GetErrorMessage(r));
329
330                         if (pTempFolderPath != NULL)
331                         {
332                                 SysLog(NID_CNT, "pFolderPath is [%s].", pTempFolderPath);
333
334                                 pValue = std::unique_ptr<Object>(new (std::nothrow) String(pTempFolderPath));
335                         }
336                         if (pValue != NULL)
337                         {
338                                 r = __pFinalOutList->Add(*(pValue.release()));
339                                 SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform Add operation to __pFinalOutList.", GetErrorMessage(r));
340                         }
341                 }
342         }
343
344         SetLastResult(r);
345         return __pFinalOutList.release();
346 }
347
348 int
349 _ContentDirectoryImpl::GetContentDirectoryItemCount(const Tizen::Base::String& contentDirectoryPath) const
350 {
351         SysLog(NID_CNT, "contentDirectoryPath is [%ls]", contentDirectoryPath.GetPointer());
352
353         int directoryItemCount = 0;
354         result r = E_SUCCESS;
355         int ret = MEDIA_CONTENT_ERROR_NONE;
356         GList* pItemList = NULL;
357         std::unique_ptr<char> pFolderId;
358         char* pTempFolderId = null;
359         std::unique_ptr<media_folder_s, FolderHandleDeleter> pFolderHandle;
360
361         SysTryReturn(NID_CNT, CheckMediaPath(contentDirectoryPath), directoryItemCount, E_INVALID_ARG,
362                         "[E_INVALID_ARG] Failed to perform CheckMediaPath operation.");
363
364         String detachedPath = contentDirectoryPath;
365
366         if (contentDirectoryPath.EndsWith(L"/"))
367         {
368                 r = detachedPath.Remove(detachedPath.GetLength() - 1, 1);
369                 SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, E_INVALID_ARG, "[E_INVALID_ARG] Failed to remove the path string.");
370         }
371
372         r = CreateFolderFilter(__isMultiContentType, detachedPath);
373         SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
374
375         ret = media_folder_foreach_folder_from_db(*(__pFilterHandle.get()), MediaFoldersCb, &pItemList);
376         r = MapCoreErrorToNativeResult(ret);
377         SysTryReturn(NID_CNT, r == E_SUCCESS, directoryItemCount, r,
378                         "[%s] Failed to perform media_folder_foreach_folder_from_db operation.", GetErrorMessage(r));
379
380         SysTryReturn(NID_CNT, pItemList != NULL, directoryItemCount, r,
381                         "[%s] pItemList for media_folder_foreach_folder_from_db is null.", GetErrorMessage(r));
382
383         for (int idx = 0; idx < (int)g_list_length(pItemList); idx++)
384         {
385                 SysLog(NID_CNT, "idx is [%d] and (int)g_list_length(pItemList) is [%d].", idx, (int)g_list_length(pItemList));
386
387                 pFolderHandle.reset(static_cast<media_folder_h>(g_list_nth_data(pItemList, idx)));
388
389                 if (pFolderHandle.get() != NULL)
390                 {
391                         pTempFolderId = pFolderId.get();
392                         ret = media_folder_get_folder_id(pFolderHandle.get(), &pTempFolderId);
393                         r = MapCoreErrorToNativeResult(ret);
394                         SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, r,
395                                         "[%s] Failed to perform media_folder_get_folder_id operation.", GetErrorMessage(r));
396                 }
397                 else
398                 {
399                         r = E_SYSTEM;
400                         SysTryReturn(NID_CNT, r != E_SUCCESS, directoryItemCount, r, "[E_SYSTEM] pFolderHandle is null.");
401                 }
402         }
403
404         if (pTempFolderId != NULL)
405         {
406                 r = CreateFolderFilter(__isMultiContentType, L"");
407                 SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
408
409                 ret = media_folder_get_media_count_from_db(pTempFolderId, *(__pFilterHandle.get()), &directoryItemCount);
410                 r = MapCoreErrorToNativeResult(ret);
411                 SysTryReturn(NID_CNT, !IsFailed(r), directoryItemCount, r,
412                                 "[%s] Failed to perform media_folder_get_media_count_from_db operation.", GetErrorMessage(r));
413         }
414
415         SysLog(NID_CNT, "directoryItemCount is [%d].", directoryItemCount);
416
417         SetLastResult(r);
418         return directoryItemCount;
419 }
420
421 // Osp column names are mapped with slp column names
422 // CONTENT_TYPE_OTHER and CONTENT_TYPE_IMAGE (0 - 13 ) are valid columns
423 // CONTENT_TYPE_VIDEO  (0 - 16 ) are valid columns
424 // CONTENT_TYPE_ALL and  CONTENT_TYPE_VIDEO (0 - 18 ) are valid columns
425 // if the given osp column is out of the specified range of the type, E_INVALID_ARG is retuned.
426 result
427 _ContentDirectoryImpl::GetSlpColumnName(String& inputCol, String sortCol) const
428 {
429         String          ospColumnName(L"");
430         String          slpColumnName(L"");
431         String          columnName(sortCol);
432         result          r = E_SUCCESS;
433         int             maxCols = MAX_QUERY_COLUMNS;
434         
435         if(!__isMultiContentType)
436         {
437                 switch (__contentType)
438                 {
439                 case CONTENT_TYPE_OTHER:
440                         //fall through
441                 case CONTENT_TYPE_IMAGE:
442                         maxCols = MAX_QUERY_COLUMNS_FOR_IMAGE_OTHERS;
443                         break;
444                 case CONTENT_TYPE_VIDEO:
445                         maxCols = MAX_QUERY_COLUMNS_FOR_VIDEO;
446                         break;
447                 case CONTENT_TYPE_AUDIO:
448                         //fall through
449                 case CONTENT_TYPE_ALL:
450                         maxCols = MAX_QUERY_COLUMNS;
451                         break;
452                 default:
453                         break;
454                 }
455         }
456         else
457         {
458                 if(!__multiContentTypeExpr.IsEmpty())
459                 {
460                         if(__multiContentTypeExpr.Contains("MEDIA_TYPE=2"))
461                         {
462                                 maxCols = MAX_QUERY_COLUMNS;
463                         }
464                         else if(__multiContentTypeExpr.Contains("MEDIA_TYPE=1"))
465                         {
466                                 maxCols = MAX_QUERY_COLUMNS_FOR_VIDEO;
467                         }
468                         else if(__multiContentTypeExpr.Contains("MEDIA_TYPE=0"))
469                         {
470                                 maxCols = MAX_QUERY_COLUMNS_FOR_IMAGE_OTHERS;
471                         }
472                 }
473         }
474
475         for (int colIndex=0; colIndex < maxCols; colIndex++)
476         {
477                 ospColumnName.Clear();
478                 slpColumnName.Clear();
479
480                 ospColumnName = dbfieldinfo[colIndex].dbFieldOspName ;
481                 slpColumnName = dbfieldinfo[colIndex].dbFieldSlpName ;
482
483                 ospColumnName.ToUpper();
484                 columnName.ToUpper();
485
486                 if (columnName == ospColumnName)
487                 {
488                         inputCol = slpColumnName;
489                         return r;
490                 }
491         }
492         return E_INVALID_ARG;
493 }
494
495 IList*
496 _ContentDirectoryImpl::GetContentDirectoryItemListN(const Tizen::Base::String& contentDirectoryPath, int pageNo, int countPerPage,
497                                                     const Tizen::Base::String& column, Tizen::Base::SortOrder sortOrder) const
498 {
499         SysLog(NID_CNT, "contentDirectoryPath is [%ls].", contentDirectoryPath.GetPointer());
500
501         result r = E_SUCCESS;
502         int totalCount = 0;
503         int totalPageCount = 0;
504         int ret = MEDIA_CONTENT_ERROR_NONE;
505         String slpColumn = L"";
506         std::unique_ptr<GList, GListDeleter> pItemList;
507         GList* pTempList = null;
508         std::unique_ptr<char> pFolderId;
509         char* pTempFolderId = null;
510         std::unique_ptr<media_folder_s, FolderHandleDeleter> pFolderHandle;
511         int offset = 0;
512
513         SysTryReturn(NID_CNT, CheckMediaPath(contentDirectoryPath), null, E_INVALID_ARG,
514                         "[E_INVALID_ARG] Failed to perform CheckMediaPath operation.");
515
516         String detachedPath = contentDirectoryPath;
517
518         if (contentDirectoryPath.EndsWith(L"/"))
519         {
520                 r = detachedPath.Remove(detachedPath.GetLength() - 1, 1);
521                 SysTryReturn(NID_CNT, !IsFailed(r), null, E_INVALID_ARG, "[E_INVALID_ARG] Failed to remove the path string.");
522         }
523
524         __pFinalOutList = std::unique_ptr<ArrayList, AllElementsDeleter>(new (std::nothrow) ArrayList());
525         SysTryReturn(NID_CNT, __pFinalOutList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] FinalOutList is null.");
526
527         r = __pFinalOutList->Construct();
528         SysTryReturn(NID_CNT, r == E_SUCCESS, null, r, "[%s] Failed to construct __pFinalOutList ArrayList.", GetErrorMessage(r));
529
530         r = CreateFolderFilter(__isMultiContentType, detachedPath);
531         SysTryReturn(NID_CNT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
532
533         if ((!column.IsEmpty()) && (sortOrder != SORT_ORDER_NONE))
534         {
535                 //__inputColumnName (osp column name) is replaced with slpColumn (slp column name).
536                 r = GetSlpColumnName(slpColumn, column);
537                 SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform GetSlpColumnName operation.", GetErrorMessage(r));
538
539                 //CopyToCharArrayN: utility function, converts a osp string to char*
540                 std::unique_ptr<char[]> pSortCol(_StringConverter::CopyToCharArrayN(slpColumn));
541                 SysTryReturn(NID_CNT, pSortCol, null, E_OUT_OF_MEMORY, "The memory is insufficient.");
542
543                 if (sortOrder == SORT_ORDER_ASCENDING)
544                 {
545                         ret = media_filter_set_order(*(__pFilterHandle.get()), MEDIA_CONTENT_ORDER_ASC, pSortCol.get(), MEDIA_CONTENT_COLLATE_DEFAULT);
546                         r = MapCoreErrorToNativeResult(ret);
547                         SysTryReturn(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, null, r,
548                                         "[%s] Failed to perform media_filter_set_order operation.", GetErrorMessage(r));
549                 }
550                 else if (sortOrder == SORT_ORDER_DESCENDING)
551                 {
552                         ret = media_filter_set_order(*(__pFilterHandle.get()), MEDIA_CONTENT_ORDER_DESC, pSortCol.get(), MEDIA_CONTENT_COLLATE_DEFAULT);
553                         r = MapCoreErrorToNativeResult(ret);
554                         SysTryReturn(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, null, r,
555                                         "[%s] Failed to perform media_filter_set_order operation.", GetErrorMessage(r));
556                 }
557         }
558
559         pTempList = pItemList.get();
560         ret = media_folder_foreach_folder_from_db(*(__pFilterHandle.get()), MediaFoldersCb, &pTempList);
561         r = MapCoreErrorToNativeResult(ret);
562         SysTryReturn(NID_CNT, !IsFailed(r), null, r,
563                         "[%s] Failed to perform media_folder_foreach_folder_from_db operation.", GetErrorMessage(r));
564
565         if (pTempList != NULL)
566         {
567                 for (int idx = 0; idx < (int)g_list_length(pTempList); idx++)
568                 {
569                         SysLog(NID_CNT, "idx is [%d] and (int)g_list_length(pItemList) is [%d].", idx, (int)g_list_length(pTempList));
570
571                         pFolderHandle.reset(static_cast<media_folder_h>(g_list_nth_data(pTempList, idx)));
572
573                         if (pFolderHandle.get() != NULL)
574                         {
575                                 pTempFolderId = pFolderId.get();
576                                 ret = media_folder_get_folder_id(pFolderHandle.get(), &pTempFolderId);
577                                 r = MapCoreErrorToNativeResult(ret);
578                                 SysTryReturn(NID_CNT, !IsFailed(r), null, r,
579                                                 "[%s] Failed to perform media_folder_get_folder_id operation.", GetErrorMessage(r));
580                         }
581                         else
582                         {
583                                 r = E_SYSTEM;
584                                 SysTryReturn(NID_CNT, r != E_SUCCESS, null, r, "[E_SYSTEM] pFolderHandle is null.");
585                         }
586                 }
587         }
588
589         if (pTempFolderId != NULL)
590         {
591                 r = CreateFolderFilter(__isMultiContentType, L"");
592                 SysTryReturn(NID_CNT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to perform CreateFolderFilter operation.");
593
594                 ret = media_folder_get_media_count_from_db(pTempFolderId, *(__pFilterHandle.get()), &totalCount);
595                 r = MapCoreErrorToNativeResult(ret);
596                 SysTryReturn(NID_CNT, !IsFailed(r), null, r,
597                                 "[%s] Failed to perform media_folder_get_media_count_from_db operation.", GetErrorMessage(r));
598
599                 SysLog(NID_CNT, "totalCount is [%d].", totalCount);
600         }
601
602         if (totalCount > 0)
603         {
604                 if ((totalCount % countPerPage) == 0)
605                 {
606                         totalPageCount = totalCount / countPerPage;
607                 }
608                 else
609                 {
610                         totalPageCount = (totalCount / countPerPage) + 1;
611                 }
612
613                 SysTryReturn(NID_CNT, ((pageNo >= 1) && (pageNo <= totalPageCount)) , NULL, E_INVALID_ARG, "[E_INVALID_ARG] (pageNo < 1) || (pageNo > totalPageCount).");
614
615                 offset = (pageNo * countPerPage) - countPerPage;
616
617                 SysLog(NID_CNT, "totalCount [%d] totalPageCount[%d] __countPerPage[%d] __pageNo[%d] offset[%d]",
618                                 totalCount, totalPageCount, countPerPage, pageNo, offset);
619
620                 ret = media_filter_set_offset(*(__pFilterHandle.get()),offset,countPerPage);
621                 r = MapCoreErrorToNativeResult(ret);
622                 SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform media_filter_set_offset operation.", GetErrorMessage(r));
623
624                 r = FillFinalOutList(pTempFolderId);
625                 SysTryReturn(NID_CNT, !IsFailed(r), null, E_SYSTEM, "[E_SYSTEM] Failed to perform FillFinalOutList operation.");
626         }
627         else if (pageNo > 1)
628         {
629                 r = E_INVALID_ARG;
630                 SysTryReturn(NID_CNT, !(IsFailed(r)), null, r, "[E_INVALID_ARG] (pageNo > 1) and (totalcount = 0).");
631         }
632         
633         SetLastResult(r);
634         return __pFinalOutList.release();
635 }
636
637 result
638 _ContentDirectoryImpl::FillFinalOutList(char* pFolderId) const
639 {
640         int ret = MEDIA_CONTENT_ERROR_NONE;
641         result r = E_SUCCESS;
642         std::unique_ptr<GList, GListDeleter> pItemList;
643         GList* pTempList = NULL;
644         std::unique_ptr<media_info_s, MediaHandleDeleter> pMediaHandle;
645
646         ContentInfo::_ContentData*                      pContentData = null;
647         ImageContentInfo::_ImageContentData*            pImageContentData = null;
648         AudioContentInfo::_AudioContentData*            pAudioContentData = null;
649         VideoContentInfo::_VideoContentData*            pVideoContentData = null;
650
651         std::unique_ptr<ImageContentInfo> pImageContentInfo;
652         std::unique_ptr<AudioContentInfo> pAudioContentInfo;
653         std::unique_ptr<VideoContentInfo> pVideoContentInfo;
654         std::unique_ptr<OtherContentInfo> pOtherContentInfo;
655
656         pTempList = pItemList.get();
657         ret = media_folder_foreach_media_from_db(pFolderId, *(__pFilterHandle.get()), MediaFolderItemsCb, &pTempList);
658         r = MapCoreErrorToNativeResult(ret);
659         SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform media_folder_foreach_media_from_db operation.");
660
661         SysTryReturnResult(NID_CNT, pTempList != NULL, r, "pItemList for media_info_foreach_media_from_db is null.");
662
663         media_content_type_e mediaType;
664
665         for (int idx = 0; idx < (int)g_list_length(pTempList); idx++)
666         {
667                 pMediaHandle.reset(static_cast<media_info_h>(g_list_nth_data(pTempList, idx)));
668
669                 ret = media_info_get_media_type(pMediaHandle.get(), &mediaType);
670                 r = MapCoreErrorToNativeResult(ret);
671                 SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform media_info_get_media_type operation.");
672
673                 switch (mediaType)
674                 {
675                 case MEDIA_CONTENT_TYPE_OTHERS:
676                         pOtherContentInfo = std::unique_ptr<OtherContentInfo>(new (std::nothrow) OtherContentInfo);
677                         SysTryReturnResult(NID_CNT, pOtherContentInfo.get() != null, E_OUT_OF_MEMORY, "Failed to create pOtherContentInfo.");
678
679                         pContentData = pOtherContentInfo->GetContentData();
680                         SysTryReturnResult(NID_CNT, pContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
681
682                         r = _ContentUtility::FillContentData(pMediaHandle.get(), pContentData);
683                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillContentData operation.");
684
685                         // Shallow copy, adds just the pointer: not the element
686                         r = __pFinalOutList->Add(*(pOtherContentInfo.release()));
687                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform Add operation to pFinalOutList.");
688
689                         break;
690                 case MEDIA_CONTENT_TYPE_IMAGE:
691                         pImageContentInfo = std::unique_ptr<ImageContentInfo>(new (std::nothrow) ImageContentInfo);
692                         SysTryReturnResult(NID_CNT, pImageContentInfo.get() != null, E_OUT_OF_MEMORY, "Failed to create pImageContentInfo.");
693
694                         pContentData = pImageContentInfo->GetContentData();
695                         SysTryReturnResult(NID_CNT, pContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
696
697                         pImageContentData = pImageContentInfo->GetImageContentData();
698                         SysTryReturnResult(NID_CNT, pImageContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
699
700                         r = _ContentUtility::FillContentData(pMediaHandle.get(), pContentData);
701                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillContentData operation.");
702
703                         r = _ContentUtility::FillImageContentData(pMediaHandle.get(), pImageContentData);
704                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform GetDataFromImageTable operation.");
705
706                         // Shallow copy, adds just the pointer: not the element
707                         r = __pFinalOutList->Add(*(pImageContentInfo.release()));
708                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform Add operation to __pFinalOutList.");
709
710                         break;
711                 case MEDIA_CONTENT_TYPE_MUSIC:
712                         //fall through
713                 case MEDIA_CONTENT_TYPE_SOUND:
714                         pAudioContentInfo = std::unique_ptr<AudioContentInfo>(new (std::nothrow) AudioContentInfo);
715                         SysTryReturnResult(NID_CNT, pAudioContentInfo.get() != null, E_OUT_OF_MEMORY, "Failed to create pAudioContentInfo.");
716
717                         pContentData = pAudioContentInfo->GetContentData();
718                         SysTryReturnResult(NID_CNT, pContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
719
720                         pAudioContentData = pAudioContentInfo->GetAudioContentData();
721                         SysTryReturnResult(NID_CNT, pAudioContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
722
723                         r = _ContentUtility::FillContentData(pMediaHandle.get(), pContentData);
724                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillContentData operation.");
725
726                         r = _ContentUtility::FillAudioContentData(pMediaHandle.get(), pAudioContentData);
727                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillAudioContentData operation.");
728
729                         // Shallow copy, adds just the pointer: not the element
730                         r = __pFinalOutList->Add(*(pAudioContentInfo.release()));
731                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform Add operation to __pFinalOutList.");
732
733                         break;
734                 case MEDIA_CONTENT_TYPE_VIDEO:
735                         pVideoContentInfo = std::unique_ptr<VideoContentInfo>(new (std::nothrow) VideoContentInfo);
736                         SysTryReturnResult(NID_CNT, pVideoContentInfo.get() != null, E_OUT_OF_MEMORY, "Failed to create pVideoContentInfo.");
737
738                         pContentData = pVideoContentInfo->GetContentData();
739                         SysTryReturnResult(NID_CNT, pContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
740
741                         pVideoContentData = pVideoContentInfo->GetVideoContentData();
742                         SysTryReturnResult(NID_CNT, pVideoContentData != null, E_OUT_OF_MEMORY, "The memory is insufficient.");
743
744                         r = _ContentUtility::FillContentData(pMediaHandle.get(), pContentData);
745                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillContentData operation.");
746
747                         r = _ContentUtility::FillVideoContentData(pMediaHandle.get(), pVideoContentData);
748                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform FillVideoContentData operation.");
749
750                         // Shallow copy, adds just the pointer: not the element
751                         r = __pFinalOutList->Add(*(pVideoContentInfo.release()));
752                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform Add operation to __pFinalOutList.");
753
754                         break;
755                 default:
756                         break;
757                 }
758         }
759
760         return r;
761 }
762
763 bool
764 _ContentDirectoryImpl::CheckMediaPath(const Tizen::Base::String& directoryPath) const
765 {
766         String phoneStr = Environment::GetMediaPath();
767         String mmcStr = Environment::GetExternalStoragePath();
768
769         if (!(directoryPath.StartsWith(phoneStr, 0) || directoryPath.StartsWith(mmcStr , 0)))
770         {
771                 String checkPhone;
772                 result r = phoneStr.SubString(0, (phoneStr.GetLength() - 1), checkPhone);
773                 SysTryReturn(NID_CNT, !IsFailed(r), false, E_INVALID_ARG, "[E_INVALID_ARG] Failed to substring operation.");
774
775                 String checkMmc;
776                 r = mmcStr.SubString(0, (mmcStr.GetLength() - 1), checkMmc);
777                 SysTryReturn(NID_CNT, !IsFailed(r), false, E_INVALID_ARG, "[E_INVALID_ARG] Failed to substring operation.");
778
779                 SysTryReturn(NID_CNT, (directoryPath.Equals(checkPhone) || directoryPath.Equals(checkMmc)), false, E_INVALID_ARG,
780                                 "[E_INVALID_ARG] The contentDirectoryPath is not valid[%ls].", directoryPath.GetPointer());
781         }
782
783         return true;
784 }
785
786 result
787 _ContentDirectoryImpl::MapCoreErrorToNativeResult(int reason) const
788 {
789         result r = E_SUCCESS;
790
791         switch (reason)
792         {
793         case MEDIA_CONTENT_ERROR_NONE:
794                 r = E_SUCCESS;
795                 break;
796
797         case MEDIA_CONTENT_ERROR_DB_BUSY:
798                 r = E_SERVICE_BUSY;
799                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_DB_BUSY");
800                 break;
801
802         case MEDIA_CONTENT_ERROR_DB_FAILED:
803                 r = E_SYSTEM;
804                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_DB_FAILED");
805                 break;
806
807         case MEDIA_CONTENT_ERROR_OUT_OF_MEMORY:
808                 r = E_OUT_OF_MEMORY;
809                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_OUT_OF_MEMORY");
810                 break;
811
812         default:
813                 SysLog(NID_CNT, "default");
814                 r = E_SYSTEM;
815                 break;
816         }
817         return r;
818 }
819
820 // Callback function registered to each media info details
821 // all items are appended to the list
822 bool
823 MediaFoldersCb(media_folder_h folder, void* pUserdata)
824 {
825         int ret  = MEDIA_CONTENT_ERROR_NONE;
826         media_folder_h new_folder = NULL;
827         ret = media_folder_clone(&new_folder, folder);
828         SysTryLog(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, "[E_SYSTEM] Propagating for media_folder_clone.");
829
830         GList** pList = (GList**)pUserdata;
831         *pList = g_list_append(*pList, new_folder);
832
833         return true;
834 }
835
836 // Callback function registered to each media info details
837 // all items are appended to the list
838 bool
839 MediaFolderItemsCb(media_info_h media, void* pUserdata)
840 {
841         int ret  = MEDIA_CONTENT_ERROR_NONE;
842         media_info_h new_media = NULL;
843         ret = media_info_clone(&new_media, media);
844         SysTryLog(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, "[E_SYSTEM] Propagating for media_info_clone.");
845
846         GList** pList = (GList**)pUserdata;
847         *pList = g_list_append(*pList, new_media);
848
849         return true;
850 }
851
852 }}