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