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