Fix memory leak
[profile/tv/apps/native/musicplayer.git] / src / data / mediadata.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
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 #include <Eina.h>
18 #include <media_content.h>
19 #include <sys/time.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include "dbg.h"
23 #include "i18n.h"
24 #include "define.h"
25 #include "song_info.h"
26 #include "album_info.h"
27 #include "category_info.h"
28 #include "folder_info.h"
29 #include "mediadata.h"
30 #include "common.h"
31
32 #define MEDIA_CONDITION_MUSIC           "(MEDIA_TYPE=3)"
33 #define MEDIA_CONDITION_INTERNAL        "(MEDIA_STORAGE_TYPE=0)"
34 #define MEDIA_CONDITION_EXTERNAL        "(MEDIA_STORAGE_TYPE=1)"
35
36 #define MUSIC_STR_UNKNOWN               N_("Unknown")
37
38 enum songlist_type {
39         E_ALL_SONGS,
40         E_ALBUM_SONGS,
41         E_FOLDER_SONGS,
42         E_PLAYLIST_SONGS,
43         E_SINGLE_SONG
44 };
45
46 struct SMediadata {
47         Eina_List *songlist;
48         Eina_List *folderlist;
49         Eina_List *folder_songlist;
50         Eina_List *albumlist;
51         Eina_List *album_songlist;
52         Eina_List *playlistslist;
53         Eina_List *playlist_songlist;
54         Eina_List *artistlist;
55         Eina_List *genrelist;
56         Eina_List *cblist;
57         CSongInfo *sinfo;
58         filter_h filter;
59         int source_type;
60         int slist_type;
61         int member_id;
62         SMediadata() {
63                 memset(this, 0, sizeof(SMediadata));
64         }
65 };
66
67
68 bool CMediadata::sm_CbTotalDuration(media_info_h md_h, void *dt)
69 {
70         audio_meta_h audio_h;
71         int dur;
72         int *tdur = (int *)dt;
73
74         if (!tdur)
75                 return false;
76
77         if (media_info_get_audio(md_h, &audio_h) != MEDIA_CONTENT_ERROR_NONE) {
78                 _ERR("Media info get audio error");
79                 return false;
80         }
81
82         dur = 0;
83         if (audio_meta_get_duration(audio_h, &dur) != MEDIA_CONTENT_ERROR_NONE)
84                 _ERR("audio duration get error");
85
86         audio_meta_destroy(audio_h);
87
88         *tdur = *tdur + dur;
89
90         return true;
91 }
92
93
94 bool CMediadata::sm_CbEachMediaData(media_info_h md_h, void *dt)
95 {
96         CMediadata *root = (CMediadata *)dt;
97
98         if (!root)
99                 return false;
100
101         root->m_HandleEachMediaData(md_h);
102
103         return true;
104 }
105
106
107 bool CMediadata::sm_CbEachFolderData(media_folder_h folder_h, void *dt)
108 {
109         CMediadata *root = (CMediadata *)dt;
110
111         if (!root)
112                 return false;
113
114         root->m_HandleEachFolderData(folder_h);
115
116         return true;
117 }
118
119
120 bool CMediadata::sm_CbEachAlbumData(media_album_h album_h, void *dt)
121 {
122         CMediadata *root = (CMediadata *)dt;
123
124         if (!root)
125                 return false;
126
127         root->m_HandleEachAlbumData(album_h);
128
129         return true;
130 }
131
132
133 bool CMediadata::sm_CbEachPlaylist(media_playlist_h ph, void *dt)
134 {
135         CMediadata *root = (CMediadata *)dt;
136
137         if (!root)
138                 return false;
139
140         root->m_HandleEachPlaylist(ph);
141
142         return true;
143 }
144
145
146 bool CMediadata::sm_CbPlaylistMember(int memb_id, media_info_h mdh, void *dt)
147 {
148         CCategoryInfo *catinfo = (CCategoryInfo *)dt;
149         CCategoryInfo::CListMember *member = NULL;
150         char *id = NULL;
151
152         if (!mdh || !catinfo)
153                 return false;
154
155         if (media_info_get_media_id(mdh, &id) != MEDIA_CONTENT_ERROR_NONE) {
156                 _ERR(" Failed to get media id ");
157                 return false;
158         }
159
160         char *thumb;
161         if (!catinfo->ThumbnailPath()) {
162                 if (media_info_get_thumbnail_path(mdh, &thumb) != MEDIA_CONTENT_ERROR_NONE)
163                         _ERR("Media thumbnail path Fetch error");
164                 catinfo->SetThumbnailPath(thumb);
165         }
166
167         member = new CCategoryInfo::CListMember;
168         if (!member) {
169                 free(id);
170                 return false;
171         }
172
173         member->memberId = memb_id;
174         member->mediaId = id;
175
176         catinfo->SetMember(member);
177
178         return true;
179 }
180
181
182 bool CMediadata::sm_CbPlaylist(media_playlist_h ph, void* dt)
183 {
184         Eina_List **list = (Eina_List **)dt;
185         SCtxtPlaylistItem *item;
186
187         if (!ph || !list)
188                 return false;
189
190         item = (SCtxtPlaylistItem *)calloc(1, sizeof(*item));
191         if (!item)
192                 return false;
193
194         if (media_playlist_get_name(ph, (char **)&(item->name)) !=
195                 MEDIA_CONTENT_ERROR_NONE) {
196                 _ERR(" Failed to read playlist name ");
197                 free(item);
198                 return false;
199         }
200
201         if (media_playlist_get_playlist_id(ph, &(item->id)) !=
202                 MEDIA_CONTENT_ERROR_NONE) {
203                 _ERR(" Failed to read playlist name ");
204                 free(item->name);
205                 free(item);
206                 return false;
207         }
208
209         *list = eina_list_append(*list, item);
210
211         return true;
212 }
213
214
215 bool CMediadata::m_HandleEachMediaData(media_info_h md_h)
216 {
217         CSongInfo *sinfo = NULL;
218         audio_meta_h audio_h = NULL;
219         char* tmpStr = NULL;
220         int tmpValue;
221         bool ret;
222
223         sinfo = new CSongInfo;
224         if (!sinfo) {
225                 _ERR("Memory alloc failed");
226                 return false;
227         }
228
229         ret = sinfo->Create();
230         if (!ret) {
231                 _ERR("CSongInfo creation failed");
232                 delete sinfo;
233                 return false;
234         }
235
236         if (media_info_get_file_path(md_h, &tmpStr)
237                 != MEDIA_CONTENT_ERROR_NONE) {
238                 _ERR("Media file path Fetch error");
239                 sinfo->Destroy();
240                 delete sinfo;
241                 return false;
242         }
243         sinfo->SetPath(tmpStr);
244
245         if (media_info_get_thumbnail_path(md_h, &tmpStr) !=
246                 MEDIA_CONTENT_ERROR_NONE)
247                 _ERR("Media thumbnail path Fetch error");
248         sinfo->SetThumbnailPath(tmpStr);
249
250         if (media_info_get_media_type(md_h,
251                 (media_content_type_e *)&tmpValue) !=
252                 MEDIA_CONTENT_ERROR_NONE)
253                 _ERR("Media type Fetch error");
254         sinfo->SetType(tmpValue);
255
256         if (media_info_get_audio(md_h, &audio_h) !=
257                 MEDIA_CONTENT_ERROR_NONE) {
258                 _ERR("Media info get audio error");
259                 sinfo->Destroy();
260                 delete sinfo;
261                 return false;
262         }
263
264         if (audio_meta_get_media_id(audio_h, &tmpStr) !=
265                 MEDIA_CONTENT_ERROR_NONE) {
266                 _ERR("Media ID Fetch error");
267                 audio_meta_destroy(audio_h);
268                 sinfo->Destroy();
269                 delete sinfo;
270                 return false;
271         }
272         sinfo->SetId(tmpStr);
273
274         if (media_info_get_title(md_h, &tmpStr) !=
275                 MEDIA_CONTENT_ERROR_NONE)
276                 _ERR("audio title get error");
277         sinfo->SetName(tmpStr);
278
279         if (audio_meta_get_artist(audio_h, &tmpStr) !=
280                 MEDIA_CONTENT_ERROR_NONE)
281                 _ERR("audio artist get error");
282         sinfo->SetArtist(tmpStr);
283
284         if (audio_meta_get_album(audio_h, &tmpStr) !=
285                 MEDIA_CONTENT_ERROR_NONE)
286                 _ERR("audio album get error");
287         sinfo->SetAlbum(tmpStr);
288
289         if (audio_meta_get_genre(audio_h, &tmpStr) !=
290                 MEDIA_CONTENT_ERROR_NONE)
291                 _ERR("audio genre get error");
292         sinfo->SetGenre(tmpStr);
293
294         if (audio_meta_get_composer(audio_h, &tmpStr) !=
295                 MEDIA_CONTENT_ERROR_NONE)
296                 _ERR("audio composer get error");
297         sinfo->SetComposer(tmpStr);
298
299         if (audio_meta_get_duration(audio_h, &tmpValue) !=
300                 MEDIA_CONTENT_ERROR_NONE)
301                 _ERR("audio duration get error");
302         sinfo->SetDuration(tmpValue);
303
304         audio_meta_destroy(audio_h);
305
306         switch (m->slist_type) {
307         case E_FOLDER_SONGS:
308                 m->folder_songlist = eina_list_append(
309                         m->folder_songlist, sinfo);
310                 break;
311
312         case E_ALBUM_SONGS:
313                 m->album_songlist = eina_list_append(
314                         m->album_songlist, sinfo);
315                 break;
316
317         case E_PLAYLIST_SONGS:
318                 sinfo->SetMemberId(m->member_id);
319                 m->playlist_songlist = eina_list_append(
320                         m->playlist_songlist, sinfo);
321                 break;
322
323         case E_SINGLE_SONG:
324                 m->sinfo = sinfo;
325                 break;
326
327         case E_ALL_SONGS:
328         default:
329                 m->songlist = eina_list_append(m->songlist, sinfo);
330                 break;
331         }
332         return true;
333 }
334
335
336 bool CMediadata::m_HandleEachFolderData(media_folder_h folder_h)
337 {
338         CFolderInfo *finfo = NULL;
339         char *tmpStr = NULL;
340         int tmpValue;
341         bool ret;
342
343         finfo = new CFolderInfo;
344         if (!finfo) {
345                 _ERR("Memory alloc failed");
346                 return false;
347         }
348
349         ret = finfo->Create();
350         if (!ret) {
351                 _ERR("CFolderInfo creation failed");
352                 delete finfo;
353                 return false;
354         }
355
356         if (media_folder_get_folder_id(folder_h, &tmpStr) !=
357                 MEDIA_CONTENT_ERROR_NONE) {
358                 _ERR("Folder ID Fetch error");
359                 finfo->Destroy();
360                 delete finfo;
361                 return false;
362         }
363         finfo->SetId(tmpStr);
364
365         if (media_folder_get_media_count_from_db(finfo->Id(),
366                 m->filter, &tmpValue) !=
367                 MEDIA_CONTENT_ERROR_NONE) {
368                 _ERR("Folder media count Fetch error");
369                 finfo->Destroy();
370                 delete finfo;
371                 return false;
372         }
373         finfo->SetCount(tmpValue);
374
375         if (media_folder_foreach_media_from_db(finfo->Id(), m->filter,
376                 sm_CbTotalDuration, &tmpValue) !=
377                 MEDIA_CONTENT_ERROR_NONE) {
378                 _ERR("Folder media count Fetch error");
379                 finfo->Destroy();
380                 delete finfo;
381                 return false;
382         }
383         finfo->SetDuration(tmpValue);
384
385         if (media_folder_get_name(folder_h, &tmpStr) !=
386                 MEDIA_CONTENT_ERROR_NONE) {
387                 _ERR("folder name Fetch error");
388                 finfo->Destroy();
389                 delete finfo;
390                 return false;
391         }
392         finfo->SetName(tmpStr);
393
394         m->folderlist = eina_list_append(m->folderlist, finfo);
395         return true;
396 }
397
398
399 bool CMediadata::m_HandleEachAlbumData(media_album_h album_h)
400 {
401         CAlbumInfo *alinfo = NULL;
402         CSongInfo *sinfo = NULL;
403         void *obj = NULL;
404         char *tmpStr = NULL;
405         int tmpValue;
406         Eina_List *l = NULL;
407         bool ret;
408
409         alinfo = new CAlbumInfo;
410         if (!alinfo) {
411                 _ERR("Memory alloc failed");
412                 return false;
413         }
414
415         ret = alinfo->Create();
416         if (!ret) {
417                 _ERR("CAlbumInfo creation failed");
418                 delete alinfo;
419                 return false;
420         }
421
422         if (media_album_get_album_id(album_h, &tmpValue) !=
423                 MEDIA_CONTENT_ERROR_NONE) {
424                 _ERR("Album ID Fetch error");
425                 alinfo->Destroy();
426                 delete alinfo;
427                 return false;
428         }
429         alinfo->SetAlbumId(tmpValue);
430
431         if (media_album_get_name(album_h, &tmpStr) !=
432                 MEDIA_CONTENT_ERROR_NONE) {
433                 _ERR("Album name Fetch error");
434                 alinfo->Destroy();
435                 delete alinfo;
436                 return false;
437         }
438         alinfo->SetName(tmpStr);
439
440         if (media_album_get_artist(album_h, &tmpStr) !=
441                 MEDIA_CONTENT_ERROR_NONE) {
442                 _ERR("Album artist Fetch error");
443                 alinfo->Destroy();
444                 delete alinfo;
445                 return false;
446         }
447         alinfo->SetArtist(tmpStr);
448
449         if (media_album_get_media_count_from_db(alinfo->AlbumId(), m->filter, &tmpValue)) {
450                 _ERR("Album artist Fetch error");
451                 alinfo->Destroy();
452                 delete alinfo;
453                 return false;
454         }
455         alinfo->SetSongCount(tmpValue);
456
457         if (m->album_songlist)
458                 m_DeleteAlbumSongList();
459
460         m_GetAlbumSongList(alinfo);
461
462         EINA_LIST_FOREACH(m->album_songlist, l, obj) {
463                 sinfo = (CSongInfo *)obj;
464                 tmpStr = sinfo->Genre();
465                 if (tmpStr) {
466                         alinfo->SetGenre(tmpStr);
467                         break;
468                 }
469         }
470
471         EINA_LIST_FOREACH(m->album_songlist, l, obj) {
472                 sinfo = (CSongInfo *)obj;
473                 tmpStr = sinfo->ThumbnailPath();
474                 if (tmpStr) {
475                         alinfo->SetThumbnailPath(tmpStr);
476                         break;
477                 }
478         }
479
480         m->albumlist = eina_list_append(m->albumlist, alinfo);
481         return true;
482 }
483
484
485 bool CMediadata::m_HandleEachPlaylist(media_playlist_h ph)
486 {
487         CCategoryInfo *catinfo = NULL;
488         char *tmpStr;
489         int tmpValue;
490         bool ret;
491
492         if (!ph)
493                 return false;
494
495         catinfo = new CCategoryInfo;
496         if (!catinfo) {
497                 _ERR("Memory alloc failed");
498                 return false;
499         }
500
501         ret = catinfo->Create();
502         if (!ret) {
503                 _ERR("CCategoryInfo Create failed");
504                 delete catinfo;
505                 return false;
506         }
507
508         if (media_playlist_get_name(ph, &tmpStr) !=
509                 MEDIA_CONTENT_ERROR_NONE) {
510                 _ERR(" Failed to read playlist name ");
511                 catinfo->Destroy();
512                 delete catinfo;
513                 return false;
514         }
515         catinfo->SetName(tmpStr);
516
517         if (media_playlist_get_playlist_id(ph, &tmpValue) !=
518                 MEDIA_CONTENT_ERROR_NONE) {
519                 _ERR(" Failed to read playlist name ");
520                 catinfo->Destroy();
521                 delete catinfo;
522                 return false;
523         }
524         catinfo->SetCategoryId(tmpValue);
525
526         if (media_playlist_get_media_count_from_db(catinfo->CategoryId(), NULL,
527                 &tmpValue) != MEDIA_CONTENT_ERROR_NONE) {
528                 _ERR(" Failed to read playlist name ");
529                 catinfo->Destroy();
530                 delete catinfo;
531                 return false;
532         }
533         catinfo->SetSongCount(tmpValue);
534
535         if (media_playlist_foreach_media_from_db(catinfo->CategoryId(), NULL,
536                 sm_CbPlaylistMember, (void *)catinfo) !=
537                 MEDIA_CONTENT_ERROR_NONE) {
538                 _ERR(" Failed to read playlist members ");
539                 catinfo->Destroy();
540                 delete catinfo;
541                 return false;
542         }
543
544         m->playlistslist = eina_list_append(m->playlistslist, catinfo);
545
546         return true;
547 }
548
549
550 void CMediadata::m_DeleteSongList(void)
551 {
552         CSongInfo *sinfo = NULL;
553         void *obj = NULL;
554
555         EINA_LIST_FREE(m->songlist, obj) {
556                 sinfo = (CSongInfo *)obj;
557                 sinfo->Destroy();
558                 delete sinfo;
559         }
560
561         m->songlist = NULL;
562 }
563
564
565 void CMediadata::m_DeleteFolderSongList(void)
566 {
567         CSongInfo *sinfo = NULL;
568         void *obj = NULL;
569
570         EINA_LIST_FREE(m->folder_songlist, obj) {
571                 sinfo = (CSongInfo *)obj;
572                 sinfo->Destroy();
573                 delete sinfo;
574         }
575
576         m->folder_songlist = NULL;
577 }
578
579
580 void CMediadata::m_DeleteAlbumSongList(void)
581 {
582         CSongInfo *sinfo = NULL;
583         void *obj = NULL;
584
585         EINA_LIST_FREE(m->album_songlist, obj) {
586                 sinfo = (CSongInfo *)obj;
587                 sinfo->Destroy();
588                 delete sinfo;
589         }
590
591         m->album_songlist = NULL;
592 }
593
594
595 void CMediadata::m_DeletePlaylistSongList(void)
596 {
597         CSongInfo *sinfo = NULL;
598         void *obj = NULL;
599
600         EINA_LIST_FREE(m->playlist_songlist, obj) {
601                 sinfo = (CSongInfo *)obj;
602                 sinfo->Destroy();
603                 delete sinfo;
604         }
605
606         m->playlist_songlist = NULL;
607 }
608
609
610 void CMediadata::m_DeleteFolderList(void)
611 {
612         CFolderInfo *finfo = NULL;
613         void *obj = NULL;
614
615         EINA_LIST_FREE(m->folderlist, obj) {
616                 finfo = (CFolderInfo *)obj;
617                 finfo->Destroy();
618                 delete finfo;
619         }
620
621         m->folderlist = NULL;
622 }
623
624
625 void CMediadata::m_DeleteAlbumList(void)
626 {
627         CAlbumInfo *alinfo = NULL;
628         void *obj = NULL;
629
630         EINA_LIST_FREE(m->albumlist, obj) {
631                 alinfo = (CAlbumInfo *)obj;
632                 alinfo->Destroy();
633                 delete alinfo;
634         }
635
636         m->albumlist = NULL;
637 }
638
639
640 void CMediadata::m_DeleteCategoryList(ECategoryType type)
641 {
642         CCategoryInfo *catinfo = NULL;
643         void *obj = NULL;
644
645         if (type == CAT_TYPE_ARTIST) {
646                 EINA_LIST_FREE(m->artistlist, obj) {
647                         catinfo = (CCategoryInfo *)obj;
648                         catinfo->Destroy();
649                         delete catinfo;
650                 }
651
652                 m->artistlist = NULL;
653         }
654         else if (type == CAT_TYPE_GENRE) {
655                 EINA_LIST_FREE(m->genrelist, obj) {
656                         catinfo = (CCategoryInfo *)obj;
657                         catinfo->Destroy();
658                         delete catinfo;
659                 }
660
661                 m->genrelist = NULL;
662         }
663         else if (type == CAT_TYPE_PLAYLISTS) {
664                 EINA_LIST_FREE(m->playlistslist, obj) {
665                         catinfo = (CCategoryInfo *)obj;
666                         catinfo->Destroy();
667                         delete catinfo;
668                 }
669
670                 m->playlistslist = NULL;
671         }
672 }
673
674
675 bool CMediadata::m_CreateFilter(void)
676 {
677         char buf[MAX_LENGTH];
678         int ret;
679
680         ret = media_filter_create(&(m->filter));
681         if (ret != MEDIA_CONTENT_ERROR_NONE) {
682                 _ERR("Media Filter Creation Failed");
683                 return false;
684         }
685
686         switch (m->source_type) {
687         case SOURCE_TYPE_TV:
688                 snprintf(buf, sizeof(buf), "%s AND %s", MEDIA_CONDITION_MUSIC,
689                         MEDIA_CONDITION_INTERNAL);
690                 break;
691
692         case SOURCE_TYPE_USB:
693                 snprintf(buf, sizeof(buf), "%s AND %s", MEDIA_CONDITION_MUSIC,
694                         MEDIA_CONDITION_EXTERNAL);
695                 break;
696
697         case SOURCE_TYPE_ALL:
698         default:
699                 snprintf(buf, sizeof(buf), "%s", MEDIA_CONDITION_MUSIC);
700                 break;
701         }
702
703         media_filter_set_condition(m->filter, buf,
704                 MEDIA_CONTENT_COLLATE_DEFAULT);
705
706         return true;
707 }
708
709
710 bool CMediadata::m_DestroyFilter(void)
711 {
712         if (media_filter_destroy(m->filter) != MEDIA_CONTENT_ERROR_NONE) {
713                 _ERR("Filter destroy failed");
714                 m->filter = NULL;
715                 return false;
716         }
717         m->filter = NULL;
718
719         return true;
720 }
721
722
723 int CMediadata::m_GetPlaylistList(void)
724 {
725         if (media_playlist_foreach_playlist_from_db(NULL, sm_CbEachPlaylist, this)) {
726                 _ERR(" Get each playlist failed ");
727                 return false;
728         }
729
730         return true;
731 }
732
733
734 void CMediadata::m_GetCategoryList(ECategoryType type)
735 {
736         CAlbumInfo *alinfo = NULL;
737         CCategoryInfo *catinfo = NULL;
738         void *obj = NULL;
739         Eina_List *l = NULL;
740         int count;
741         bool ret;
742
743         if (!m->albumlist)
744                 return;
745
746         count = 0;
747         EINA_LIST_FOREACH(m->albumlist, l, obj) {
748                 alinfo = (CAlbumInfo *)obj;
749                 if (type == CAT_TYPE_ARTIST)
750                         catinfo = CCategoryInfo::FindCategory(m->artistlist, alinfo->Artist());
751                 else
752                         catinfo = CCategoryInfo::FindCategory(m->genrelist, alinfo->Genre());
753
754                 if (!catinfo) {
755                         catinfo = new CCategoryInfo();
756
757                         ret = catinfo->Create();
758                         if (!ret) {
759                                 delete catinfo;
760                                 continue;
761                         }
762
763                         catinfo->SetCategoryId(++count);
764                         catinfo->SetAlbumCount(1);
765                         catinfo->SetSongCount(alinfo->SongCount());
766                         if (type == CAT_TYPE_ARTIST) {
767                                 if (alinfo->Artist())
768                                         catinfo->SetName(alinfo->Artist());
769                                 else
770                                         catinfo->SetName(_(MUSIC_STR_UNKNOWN));
771
772                                 m->artistlist = eina_list_append(
773                                         m->artistlist, catinfo);
774                         }
775                         else {
776                                 if (alinfo->Genre())
777                                         catinfo->SetName(alinfo->Genre());
778                                 else
779                                         catinfo->SetName(_(MUSIC_STR_UNKNOWN));
780
781                                 m->genrelist = eina_list_append(
782                                         m->genrelist, catinfo);
783                         }
784                 }
785                 else {
786                         catinfo->SetAlbumCount(catinfo->AlbumCount() + 1);
787                         catinfo->SetSongCount(catinfo->SongCount() + alinfo->SongCount());
788                 }
789
790                 catinfo->SetAlbumInfo(alinfo);
791         }
792 }
793
794
795 int CMediadata::m_GetPlaylistSongList(CCategoryInfo *catinfo)
796 {
797         media_info_h mdh;
798         Eina_List *l = NULL;
799         CCategoryInfo::CListMember *member = NULL;
800         void *obj = NULL;
801         int r;
802
803         if (!catinfo || !catinfo->MemberList()) {
804                 _ERR(" Invalid argument ");
805                 return false;
806         }
807
808         m->slist_type = E_PLAYLIST_SONGS;
809
810         EINA_LIST_FOREACH(catinfo->MemberList(), l, obj) {
811                 member = (CCategoryInfo::CListMember *)obj;
812                 if (!member->mediaId)
813                         continue;
814
815                 r = media_info_get_media_from_db(member->mediaId, &mdh);
816                 if (r != MEDIA_CONTENT_ERROR_NONE) {
817                         _ERR("unable to get handle from id");
818                         continue;
819                 }
820
821                 m->member_id = member->memberId;
822                 if (!m_HandleEachMediaData(mdh))
823                         _ERR("unable to get media data");
824         }
825
826         return true;
827 }
828
829
830 int CMediadata::m_GetFolderSongList(CFolderInfo *finfo)
831 {
832         char *id = NULL;
833         int r;
834
835         id = finfo->Id();
836
837         m->slist_type = E_FOLDER_SONGS;
838         r = media_folder_foreach_media_from_db(id, m->filter,
839                 sm_CbEachMediaData, (void *)this);
840         if (r != MEDIA_CONTENT_ERROR_NONE) {
841                 _ERR("Media folder foreach folder from db failed");
842                 return false;
843         }
844
845         return true;
846 }
847
848
849 int CMediadata::m_GetFolderList(void)
850 {
851         int r;
852
853         r = media_folder_foreach_folder_from_db(m->filter,
854                 sm_CbEachFolderData, (void *)this);
855         if (r != MEDIA_CONTENT_ERROR_NONE) {
856                 _ERR("Media album foreach album from db failed");
857                 return false;
858         }
859
860         return true;
861 }
862
863
864 int CMediadata::m_GetAlbumSongList(CAlbumInfo *alinfo)
865 {
866         int id;
867         int r;
868
869         id = alinfo->AlbumId();
870
871         m->slist_type = E_ALBUM_SONGS;
872         r = media_album_foreach_media_from_db(id, m->filter,
873                 sm_CbEachMediaData, (void *)this);
874         if (r != MEDIA_CONTENT_ERROR_NONE) {
875                 _ERR("Media folder foreach folder from db failed");
876                 return false;
877         }
878
879         return true;
880 }
881
882
883 int CMediadata::m_GetAlbumList(void)
884 {
885         int r;
886
887         r = media_album_foreach_album_from_db(m->filter,
888                 sm_CbEachAlbumData, (void *)this);
889         if (r != MEDIA_CONTENT_ERROR_NONE) {
890                 _ERR("Media album foreach album from db failed");
891                 return false;
892         }
893
894         return true;
895 }
896
897
898 int CMediadata::m_GetSongList(void)
899 {
900         int r;
901
902         m->slist_type = E_ALL_SONGS;
903         r = media_info_foreach_media_from_db(m->filter,
904                 sm_CbEachMediaData, (void *)this);
905         if (r != MEDIA_CONTENT_ERROR_NONE) {
906                 _ERR("Media folder foreach folder from db failed");
907                 return false;
908         }
909
910         return true;
911 }
912
913
914 void CMediadata::m_UpdateLists(void)
915 {
916         bool r;
917
918         r = m_CreateFilter();
919         if (r == false) {
920                 _ERR("Media Filter Creation Failed");
921                 return;
922         }
923
924         if (m->songlist)
925                 m_DeleteSongList();
926         m_GetSongList();
927
928         if (m->albumlist)
929                 m_DeleteAlbumList();
930         m_GetAlbumList();
931
932         if (m->artistlist)
933                 m_DeleteCategoryList(CAT_TYPE_ARTIST);
934         m_GetCategoryList(CAT_TYPE_ARTIST);
935
936         if (m->genrelist)
937                 m_DeleteCategoryList(CAT_TYPE_GENRE);
938         m_GetCategoryList(CAT_TYPE_GENRE);
939
940         if (m->folderlist)
941                 m_DeleteFolderList();
942         m_GetFolderList();
943
944         r = m_DestroyFilter();
945         if (r == false)
946                 _ERR("Media Filter Creation Failed");
947 }
948
949
950 bool CMediadata::Create(void)
951 {
952         if (m)
953                 return false;
954         
955         m = new SMediadata;
956         if (!m) {
957                 _ERR("m calloc failed");
958                 return false;
959         }
960
961         int r;
962         r = media_content_connect();
963         if (r != MEDIA_CONTENT_ERROR_NONE) {
964                 _ERR("Media Content Connect Failed");
965                 delete m;
966                 m = NULL;
967                 return false;
968         }
969
970         CMediaContentDbUpdateListener::Create();
971
972         m->source_type = SOURCE_TYPE_NONE;
973
974         return true;
975 }
976
977
978 void CMediadata::Destroy(void)
979 {
980         if (!m)
981                 return;
982
983         int r;
984         struct SCbInfo *cbinfo;
985         void *obj;
986
987         m_DeleteSongList();
988         m_DeleteAlbumList();
989         m_DeleteAlbumSongList();
990         m_DeleteFolderList();
991         m_DeleteFolderSongList();
992         m_DeleteCategoryList(CAT_TYPE_ARTIST);
993         m_DeleteCategoryList(CAT_TYPE_GENRE);
994         m_DeleteCategoryList(CAT_TYPE_PLAYLISTS);
995         m_DeletePlaylistSongList();
996         if (m->sinfo && m->sinfo->FlagCreate())
997                 m->sinfo->Destroy();
998         delete m->sinfo;
999
1000         EINA_LIST_FREE(m->cblist, obj) {
1001                 cbinfo = (SCbInfo *)obj;
1002                 free(cbinfo);
1003         }
1004
1005         CMediaContentDbUpdateListener::Destroy();
1006
1007         r = media_content_disconnect();
1008         if (r != MEDIA_CONTENT_ERROR_NONE)
1009                 _ERR("Media Content Connect Failed");
1010
1011         delete m;
1012 }
1013
1014
1015 struct SCbInfo *CMediadata::AddCallback(int type,
1016                 void (*cb)(void *), void *data)
1017 {
1018         struct SCbInfo *cbinfo;
1019
1020         if (!m || !cb)
1021                 return NULL;
1022
1023         cbinfo = (SCbInfo *)calloc(1, sizeof(*cbinfo));
1024         if (!cbinfo)
1025                 return NULL;
1026
1027         cbinfo->cb = cb;
1028         cbinfo->data = data;
1029         cbinfo->type = type;
1030
1031         m->cblist = eina_list_append(m->cblist, cbinfo);
1032
1033         return cbinfo;
1034 }
1035
1036
1037 bool CMediadata::RemoveCallback(struct SCbInfo *cbinfo)
1038 {
1039         if (!m)
1040                 return false;
1041
1042         if (!cbinfo)
1043                 return false;
1044
1045         m->cblist = eina_list_remove(m->cblist,
1046                         cbinfo);
1047         free(cbinfo);
1048
1049         return true;
1050 }
1051
1052
1053
1054 Eina_List *CMediadata::Medialist(int source_type, int EListType, void *info)
1055 {
1056         if (!m)
1057                 return NULL;
1058
1059         if (source_type != m->source_type) {
1060                 m->source_type = source_type;
1061                 m_UpdateLists();
1062         }
1063
1064         switch (EListType) {
1065         case LIST_TYPE_SONG:
1066                 return m->songlist;
1067
1068         case LIST_TYPE_ALBUM:
1069                 return m->albumlist;
1070
1071         case LIST_TYPE_ALBUM_SONG:
1072                 if (m->album_songlist)
1073                         m_DeleteAlbumSongList();
1074                 m_GetAlbumSongList((CAlbumInfo *)info);
1075                 return m->album_songlist;
1076
1077         case LIST_TYPE_FOLDER:
1078                 return m->folderlist;
1079
1080         case LIST_TYPE_FOLDER_SONG:
1081                 if (m->folder_songlist)
1082                         m_DeleteFolderSongList();
1083                 m_GetFolderSongList((CFolderInfo *)info);
1084                 return m->folder_songlist;
1085
1086         case LIST_TYPE_ARTIST:
1087                 return m->artistlist;
1088
1089         case LIST_TYPE_GENRE:
1090                 return m->genrelist;
1091
1092         case LIST_TYPE_PLAYLISTS:
1093                 if (m->playlistslist)
1094                         m_DeleteCategoryList(CAT_TYPE_PLAYLISTS);
1095                 m_GetPlaylistList();
1096                 return m->playlistslist;
1097
1098         case LIST_TYPE_PLAYLISTS_SONG:
1099                 if (m->playlist_songlist)
1100                         m_DeletePlaylistSongList();
1101                 m_GetPlaylistSongList((CCategoryInfo *)info);
1102                 return m->playlist_songlist;
1103
1104         default:
1105                 _ERR(" Wrong list type ");
1106                 break;
1107         }
1108
1109         return NULL;
1110 }
1111
1112 CSongInfo *CMediadata::SongByUri(char *uri)
1113 {
1114         if (!m)
1115                 return NULL;
1116
1117         filter_h filter;
1118         char buf[MAX_LENGTH];
1119         int r;
1120
1121         if (!uri)
1122                 return NULL;
1123
1124         if (m->sinfo && m->sinfo->FlagCreate()) {
1125                 m->sinfo->Destroy();
1126         }
1127
1128         delete m->sinfo;
1129         m->sinfo = NULL;
1130
1131         r = media_filter_create(&filter);
1132         if (r != MEDIA_CONTENT_ERROR_NONE) {
1133                 _ERR("Media Filter Creation Failed");
1134                 return NULL;
1135         }
1136
1137         snprintf(buf, sizeof(buf), "%s AND (MEDIA_PATH LIKE '%s%%')",
1138                         MEDIA_CONDITION_MUSIC,
1139                         uri);
1140
1141         media_filter_set_condition(filter, buf,
1142                         MEDIA_CONTENT_COLLATE_DEFAULT);
1143
1144         m->slist_type = E_SINGLE_SONG;
1145         r = media_info_foreach_media_from_db(filter, sm_CbEachMediaData,
1146                         (void *)this);
1147         if (r != MEDIA_CONTENT_ERROR_NONE)
1148                 _ERR("Failed to fetch media info");
1149
1150         if (media_filter_destroy(filter) != MEDIA_CONTENT_ERROR_NONE)
1151                 _ERR("Filter destroy failed");
1152
1153         return m->sinfo;
1154 }
1155
1156
1157 bool CMediadata::SetPlayedTime(char *media_id)
1158 {
1159         if (!m)
1160                 return false;
1161
1162         media_info_h mdh;
1163         audio_meta_h adh;
1164         time_t ptime;
1165         int r;
1166
1167         if (!media_id) {
1168                 _ERR("Invalid parameter");
1169                 return false;
1170         }
1171
1172         r = media_info_get_media_from_db(media_id, &mdh);
1173         if (r != MEDIA_CONTENT_ERROR_NONE) {
1174                 _ERR("Failed to get media from id");
1175                 return false;
1176         }
1177
1178         r = media_info_get_audio(mdh, &adh);
1179         if (r != MEDIA_CONTENT_ERROR_NONE) {
1180                 _ERR("Failed to get audio from media");
1181                 media_info_destroy(mdh);
1182                 return false;
1183         }
1184
1185         ptime = time(NULL);
1186
1187         r = audio_meta_set_played_time(adh, ptime);
1188         if (r != MEDIA_CONTENT_ERROR_NONE) {
1189                 _ERR("Failed to set played time");
1190                 audio_meta_destroy(adh);
1191                 media_info_destroy(mdh);
1192                 return false;
1193         }
1194
1195         r = audio_meta_update_to_db(adh);
1196         if (r != MEDIA_CONTENT_ERROR_NONE) {
1197                 _ERR("Failed to update to db");
1198                 audio_meta_destroy(adh);
1199                 media_info_destroy(mdh);
1200                 return false;
1201         }
1202
1203         audio_meta_destroy(adh);
1204         media_info_destroy(mdh);
1205
1206         return true;
1207 }
1208
1209
1210 bool CMediadata::InsertPlaylist(const char *name, Eina_List *idlist)
1211 {
1212         if (!m)
1213                 return false;
1214
1215         media_playlist_h ph;
1216         int r;
1217         Eina_List *l;
1218         char *id = NULL;
1219         void *obj;
1220
1221         if (!name)
1222                 return false;
1223
1224         r = media_playlist_insert_to_db(name, &ph);
1225         if (r != MEDIA_CONTENT_ERROR_NONE) {
1226                 _ERR(" Failed to insert ");
1227                 return false;
1228         }
1229
1230         EINA_LIST_FOREACH(idlist, l, obj) {
1231                 id = (char *)obj;
1232                 media_playlist_add_media(ph, id);
1233         }
1234
1235         media_playlist_update_to_db(ph);
1236
1237         return true;
1238 }
1239
1240
1241 bool CMediadata::ExistPlaylist(const char *name)
1242 {
1243         if (!m)
1244                 return false;
1245
1246         Eina_List *l;
1247         CCategoryInfo *catinfo;
1248         void *obj;
1249
1250         if (!name)
1251                 return false;
1252
1253         if (!m->playlistslist)
1254                 return false;
1255
1256         EINA_LIST_FOREACH(m->playlistslist, l, obj) {
1257                 catinfo = (CCategoryInfo *)obj;
1258                 if (catinfo->Name() && !strcmp(catinfo->Name(), name))
1259                         return true;
1260         }
1261
1262         return false;
1263 }
1264
1265
1266 bool CMediadata::DeletePlaylist(int id)
1267 {
1268         if (!m)
1269                 return false;
1270
1271         int r;
1272
1273         r = media_playlist_delete_from_db(id);
1274         if (r != MEDIA_CONTENT_ERROR_NONE) {
1275                 _ERR(" Failed to delete playlist");
1276                 return false;
1277         }
1278
1279         return true;
1280 }
1281
1282
1283 bool CMediadata::RenamePlaylist(int id, const char *name)
1284 {
1285         if (!m)
1286                 return false;
1287
1288         int r;
1289         media_playlist_h ph;
1290
1291         r = media_playlist_get_playlist_from_db(id, &ph);
1292         if (r != MEDIA_CONTENT_ERROR_NONE) {
1293                 _ERR(" Failed to get playlist");
1294                 return false;
1295         }
1296
1297         r = media_playlist_set_name(ph, name);
1298         if (r != MEDIA_CONTENT_ERROR_NONE) {
1299                 _ERR(" Failed to set playlist name");
1300                 return false;
1301         }
1302
1303         media_playlist_update_to_db(ph);
1304
1305         return true;
1306 }
1307
1308
1309 bool CMediadata::AddmediaPlaylist(int lid, Eina_List *idlist)
1310 {
1311         if (!m)
1312                 return false;
1313
1314         media_playlist_h ph;
1315         int r;
1316         Eina_List *l;
1317         char *id;
1318         void *obj;
1319
1320         if (!idlist)
1321                 return false;
1322
1323         r = media_playlist_get_playlist_from_db(lid, &ph);
1324         if (r != MEDIA_CONTENT_ERROR_NONE) {
1325                 _ERR(" Failed to get playlist");
1326                 return false;
1327         }
1328
1329         EINA_LIST_FOREACH(idlist, l, obj) {
1330                 id = (char *)obj;
1331                 media_playlist_add_media(ph, id);
1332         }
1333
1334         media_playlist_update_to_db(ph);
1335
1336         return true;
1337 }
1338
1339
1340 bool CMediadata::RemovemediaPlaylist(int lid, Eina_List *idlist)
1341 {
1342         if (!m)
1343                 return false;
1344
1345         media_playlist_h ph;
1346         int r;
1347         Eina_List *l;
1348         CSongInfo *sinfo;
1349         void *obj;
1350         int id;
1351
1352         if (!idlist) {
1353                 _ERR(" Invalid argument ");
1354                 return false;
1355         }
1356
1357         r = media_playlist_get_playlist_from_db(lid, &ph);
1358         if (r != MEDIA_CONTENT_ERROR_NONE) {
1359                 _ERR(" Failed to get playlist");
1360                 return false;
1361         }
1362
1363         EINA_LIST_FOREACH(idlist, l, obj) {
1364                 sinfo = (CSongInfo *)obj;
1365                 id = sinfo->MemberId();
1366                 if (id)
1367                         media_playlist_remove_media(ph, id);
1368         }
1369
1370         media_playlist_update_to_db(ph);
1371
1372         return true;
1373 }
1374
1375
1376 Eina_List *CMediadata::PlaylistsForCtxt(void)
1377 {
1378         Eina_List *list;
1379
1380         list = NULL;
1381         if (media_playlist_foreach_playlist_from_db(NULL, sm_CbPlaylist, &list))
1382                 _ERR(" Get playlist failed ");
1383
1384         return list;
1385 }
1386
1387
1388 void CMediadata::OnUpdated(const SEntity *entity)
1389 {
1390         Eina_List *l = NULL;
1391         SCbInfo *cbinfo = NULL;
1392         void *obj = NULL;
1393
1394         if (entity->err != MEDIA_CONTENT_ERROR_NONE || !m)
1395                 return;
1396
1397         m->source_type = SOURCE_TYPE_NONE;
1398         EINA_LIST_FOREACH(m->cblist, l, obj) {
1399                 cbinfo = (SCbInfo *)obj;
1400                 if (cbinfo->type == E_CONTENT_UPDATE && cbinfo->cb)
1401                         cbinfo->cb(cbinfo->data);
1402         }
1403 }