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