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