[content] Fix memory leak
[platform/framework/native/content.git] / src / FCnt_PlayListManagerImpl.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_PlayListStatisticsImpl.cpp
18  * @brief               This is the implementation file for the %_PlayListStatisticsImpl class.
19  *
20  * This file contains implementation of the %_PlayListStatisticsImpl class.
21  */
22
23 #include <FBaseSysLog.h>
24 #include <FBaseInteger.h>
25 #include <FBaseLongLong.h>
26 #include <FBaseFloat.h>
27 #include <FCntPlayList.h>
28 #include <FCntPlayListManager.h>
29 #include <FBase_StringConverter.h>
30 #include <FCnt_PlayListImpl.h>
31 #include <FCnt_PlayListManagerImpl.h>
32
33 using namespace Tizen::Base;
34 using namespace Tizen::Base::Collection;
35 using namespace Tizen::Io;
36
37 namespace Tizen { namespace Content
38 {
39
40 // Declaration for Callback function registered to playlist details
41 bool MediaPlayListCb(media_playlist_h playlistHandle, void *pUserData);
42
43 _PlayListManagerImpl::_PlayListManagerImpl(void)
44         : Object()
45         , __pFilterHandle(NULL)
46 {
47
48 }
49
50
51 //(disconnects the DB connection)
52 _PlayListManagerImpl::~_PlayListManagerImpl(void)
53 {
54         int ret = MEDIA_CONTENT_ERROR_NONE;
55         result r = E_SUCCESS;
56
57         ret = media_content_disconnect();
58         r = MapCoreErrorToNativeResult(ret);
59         SysTryLog(r == E_SUCCESS, "[%s] Propagating for media_content_disconnect.", GetErrorMessage(r));
60
61         SysLog(NID_CNT, "media_content_disconnect result[%d].", ret);
62 }
63
64  _PlayListManagerImpl*
65  _PlayListManagerImpl::GetInstance(PlayListManager& playListManager)
66 {
67         return (&playListManager != null) ? playListManager.__pImpl : null;
68 }
69
70 const _PlayListManagerImpl*
71 _PlayListManagerImpl::GetInstance(const PlayListManager& playListManager)
72 {
73         return (&playListManager != null) ? playListManager.__pImpl : null;
74 }
75
76 result
77 _PlayListManagerImpl::Construct(void)
78 {
79         result r = E_SUCCESS;
80         int ret = MEDIA_CONTENT_ERROR_NONE;
81
82         ret = media_content_connect();
83         r = MapCoreErrorToNativeResult(ret);
84         SysTryReturnResult(NID_CNT, r == E_SUCCESS , r, "Propagating for media_content_disconnect.");
85
86         SysLog(NID_CNT, "media_content_connect result[%d].", ret);
87
88         return r;
89 }
90
91 result
92 _PlayListManagerImpl::CreateFilter(const Tizen::Base::String& playListName) const
93 {
94         std::unique_ptr<char[]> pInputCond;
95         filter_h tempFilter = NULL;
96         String inputCondition = L"PLAYLIST_NAME = ";
97         String nameExpr(playListName);
98
99         int ret = media_filter_create(&tempFilter);
100         result r = MapCoreErrorToNativeResult(ret);
101         SysTryReturnResult(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, r, "Failed to perform media_filter_create operation.");
102
103         std::unique_ptr<filter_s, FilterDeleter> pFilterHandle(tempFilter);
104         SysTryReturnResult(NID_CNT, pFilterHandle != null, E_OUT_OF_MEMORY, "pFilterHandle is null.");
105
106         if (!nameExpr.IsEmpty())
107         {
108                 r = nameExpr.Replace("\'", "''");
109                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Replace operation for nameExpr.");
110
111                 r = nameExpr.Insert('\'', 0);
112                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Insert operation for nameExpr.");
113
114                 r = nameExpr.Insert('\'', nameExpr.GetLength());
115                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Insert operation for nameExpr.");
116
117                 r = inputCondition.Append(nameExpr);
118                 SysTryReturnResult(NID_CNT, r == E_SUCCESS, r, "Failed to perform Append operation for inputCondition.");
119         }
120
121         if (!inputCondition.IsEmpty())
122         {
123                 //CopyToCharArrayN: utility function, converts a osp string to char*
124                 pInputCond = std::unique_ptr<char[]>(_StringConverter::CopyToCharArrayN(inputCondition));
125                 SysTryReturnResult(NID_CNT, pInputCond, E_OUT_OF_MEMORY, "The memory is insufficient.");
126
127                 SysLog(NID_CNT, "pInputCond is [%s]", pInputCond.get());
128
129                 ret = media_filter_set_condition(pFilterHandle.get(), pInputCond.get(), MEDIA_CONTENT_COLLATE_DEFAULT);
130                 r = MapCoreErrorToNativeResult(ret);
131                 SysTryReturnResult(NID_CNT, ret == MEDIA_CONTENT_ERROR_NONE, r, "Failed to perform media_filter_set_condition operation.");
132         }
133
134         __pFilterHandle.reset(pFilterHandle.release());
135
136         return  r;
137 }
138
139 PlayList*
140 _PlayListManagerImpl::GetPlayListN(const Tizen::Base::String& playListName) const
141 {
142         std::unique_ptr<GList, GListDeleter> pItemList;
143         GList* pTempList = null;
144         std::unique_ptr<media_playlist_s, PlayListHandleDeleter> playListHandle;
145         int playlistId = 0;
146         std::unique_ptr<PlayList> pFinalOutplayList;
147         int ret = MEDIA_CONTENT_ERROR_NONE;
148
149         result r = CreateFilter(playListName);
150         SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_DATABASE, "[E_DATABASE] Failed to perform CreateFilter operation.");
151
152         pTempList = pItemList.get();
153         ret = media_playlist_foreach_playlist_from_db(__pFilterHandle.get(), MediaPlayListCb, &pTempList);
154         r = MapCoreErrorToNativeResult(ret);
155         SysTryReturn(NID_CNT, r == E_SUCCESS , null, r, "[%s] Failed to perform media_playlist_foreach_playlist_from_db operation.", GetErrorMessage(r));
156
157         if (pTempList == NULL)
158         {
159                 r = E_INVALID_ARG; // No match found.
160         }
161         else
162         {
163                 playListHandle.reset(static_cast<media_playlist_h>(g_list_nth_data(pTempList, 0)));
164                 if (playListHandle.get() != NULL)
165                 {
166                         ret = media_playlist_get_playlist_id(playListHandle.get(), &playlistId);
167                         r = MapCoreErrorToNativeResult(ret);
168                         SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform media_playlist_get_playlist_id operation.", GetErrorMessage(r));
169
170                         pFinalOutplayList = std::unique_ptr<PlayList>(new (std::nothrow) PlayList());
171                         SysTryReturn(NID_CNT, pFinalOutplayList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] FinalOutList  is null.");
172
173                         r = pFinalOutplayList->ConstructPlayList(playListName);
174                         SysTryReturn(NID_CNT, r == E_SUCCESS, null, r, "[%s] Failed to perform ConstructPlayList operation for pFinalOutplayList.", GetErrorMessage(r));
175                 }
176         }
177
178         SetLastResult(r);
179         return pFinalOutplayList.release();
180 }
181
182 result
183 _PlayListManagerImpl::RemovePlayList(const Tizen::Base::String& playListName)
184 {
185         std::unique_ptr<GList, GListDeleter> pItemList;
186         GList* pTempList = null;
187         std::unique_ptr<media_playlist_s, PlayListHandleDeleter> playListHandle;
188         int playlistId = 0;
189         int ret = MEDIA_CONTENT_ERROR_NONE;
190
191         result r = CreateFilter(playListName);
192         SysTryReturnResult(NID_CNT, r == E_SUCCESS, E_DATABASE, "Failed to perform CreateFilter operation.");
193
194         pTempList = pItemList.get();
195         ret = media_playlist_foreach_playlist_from_db(__pFilterHandle.get(), MediaPlayListCb, &pTempList);
196         r = MapCoreErrorToNativeResult(ret);
197         SysTryReturnResult(NID_CNT, r == E_SUCCESS , r, "Failed to perform media_playlist_foreach_playlist_from_db operation.");
198
199         if (pTempList == NULL)
200         {
201                 r = E_INVALID_ARG; // No match found.
202         }
203         else
204         {
205                 playListHandle.reset(static_cast<media_playlist_h>(g_list_nth_data(pTempList, 0)));
206
207                 if (playListHandle.get() != NULL)
208                 {
209                         ret = media_playlist_get_playlist_id(playListHandle.get(), &playlistId);
210                         r = MapCoreErrorToNativeResult(ret);
211                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform media_playlist_get_playlist_id operation.");
212
213                         ret = media_playlist_delete_from_db(playlistId);
214                         r = MapCoreErrorToNativeResult(ret);
215                         SysTryReturnResult(NID_CNT, !IsFailed(r), r, "Failed to perform media_playlist_delete_from_db operation.");
216                 }
217         }
218
219         return r;
220 }
221
222 int
223 _PlayListManagerImpl::GetAllPlayListCount(void) const
224 {
225         int playlistCount = 0;
226
227         int ret = media_playlist_get_playlist_count_from_db(NULL, &playlistCount);
228         result r = MapCoreDatabaseErrorToNativeResult(ret);
229
230         SysLog(NID_CNT, "GetAllPlayListCount is [%d] and result is [%s]", playlistCount, GetErrorMessage(r));
231
232         SetLastResult(r);
233         return playlistCount;
234 }
235
236 Tizen::Base::Collection::IList*
237 _PlayListManagerImpl::GetAllPlayListNameN(void) const
238 {
239         std::unique_ptr<GList, GListDeleter> pItemList;
240         GList* pTempList = null;
241         std::unique_ptr<media_playlist_s, PlayListHandleDeleter> playListHandle;
242         char* pTempListName = null;
243         std::unique_ptr<Object> pValue;
244         std::unique_ptr<ArrayList, AllElementsDeleter> pNamesList;
245
246         pTempList = pItemList.get();
247         int ret = media_playlist_foreach_playlist_from_db(NULL, MediaPlayListCb, &pTempList);
248         result r = MapCoreDatabaseErrorToNativeResult(ret);
249         SysTryReturn(NID_CNT, r == E_SUCCESS , null, r, "[%s] Failed to perform media_playlist_foreach_playlist_from_db operation.", GetErrorMessage(r));
250
251         pNamesList = std::unique_ptr<ArrayList, AllElementsDeleter>(new (std::nothrow) ArrayList());
252         SysTryReturn(NID_CNT, pNamesList.get() != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] FinalOutList  is null.");
253
254         r = pNamesList->Construct();
255         SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
256
257         if (pTempList)
258         {
259                 for (int idx = 0; idx < (int)g_list_length(pTempList); idx++)
260                 {
261                         playListHandle.reset(static_cast<media_playlist_h>(g_list_nth_data(pTempList, idx)));
262
263                         if (playListHandle.get() != NULL)
264                         {
265                                 ret = media_playlist_get_name(playListHandle.get(), &pTempListName);
266                                 r = MapCoreDatabaseErrorToNativeResult(ret);
267                                 SysTryReturn(NID_CNT, !IsFailed(r), null, r, "[%s] Failed to perform media_playlist_get_name operation.", GetErrorMessage(r));
268
269                                 if (pTempListName != null)
270                                 {
271                                         SysLog(NID_CNT, "pPlayListName is [%s]", pTempListName);
272
273                                         std::unique_ptr<char[]> pPlayListName(pTempListName);
274                                         SysTryReturn(NID_CNT, pPlayListName != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] pPlayListName is null.");
275
276                                         pValue = std::unique_ptr<Object>(new (std::nothrow) String(pPlayListName.get()));
277                                         SysTryReturn(NID_CNT, pValue != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
278                                 }
279                                 if (pValue.get() != NULL)
280                                 {
281                                         r = pNamesList->Add(*(pValue.release()));
282                                         SysTryReturn(NID_CNT, !IsFailed(r), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
283                                 }
284                         }
285                 }
286         }
287
288         SetLastResult(r);
289         return pNamesList.release();
290 }
291
292 result
293 _PlayListManagerImpl::MapCoreErrorToNativeResult(int reason) const
294 {
295         result r = E_SUCCESS;
296
297         switch (reason)
298         {
299         case MEDIA_CONTENT_ERROR_NONE:
300                 r = E_SUCCESS;
301                 break;
302
303         case MEDIA_CONTENT_ERROR_INVALID_PARAMETER:
304                 r = E_INVALID_ARG;
305                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_INVALID_PARAMETER");
306                 break;
307
308         case MEDIA_CONTENT_ERROR_DB_FAILED:
309                 r = E_DATABASE;
310                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_DB_FAILED");
311                 break;
312
313         case MEDIA_CONTENT_ERROR_DB_BUSY:
314                 r = E_SERVICE_BUSY;
315                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_DB_BUSY");
316                 break;
317
318         default:
319                 SysLog(NID_CNT, "default");
320                 r = E_DATABASE;
321                 break;
322         }
323         return r;
324 }
325
326 result
327 _PlayListManagerImpl::MapCoreDatabaseErrorToNativeResult(int reason) const
328 {
329         result r = E_SUCCESS;
330
331         switch (reason)
332         {
333         case MEDIA_CONTENT_ERROR_NONE:
334                 r = E_SUCCESS;
335                 break;
336
337         case MEDIA_CONTENT_ERROR_DB_FAILED:
338                 r = E_DATABASE;
339                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_DB_FAILED");
340                 break;
341
342         case MEDIA_CONTENT_ERROR_DB_BUSY:
343                 r = E_SERVICE_BUSY;
344                 SysLog(NID_CNT, "MEDIA_CONTENT_ERROR_DB_BUSY");
345                 break;
346
347         default:
348                 SysLog(NID_CNT, "default");
349                 r = E_DATABASE;
350                 break;
351         }
352         return r;
353 }
354
355 bool
356 MediaPlayListCb(media_playlist_h playlistHandle, void *pUserData)
357 {
358         media_playlist_h newPlayListHandle = NULL;
359         media_playlist_clone(&newPlayListHandle, playlistHandle);
360
361         GList** pList = (GList**)pUserData;
362         *pList = g_list_append(*pList, newPlayListHandle);
363
364         return true;
365 }
366
367 }}