935fbbc49b5a8aebec0774ac125f8388902ae0cd
[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                 }
668
669                 m->playlistslist = NULL;
670         }
671 }
672
673
674 bool CMediadata::m_CreateFilter(void)
675 {
676         char buf[MAX_LENGTH];
677         int ret;
678
679         ret = media_filter_create(&(m->filter));
680         if (ret != MEDIA_CONTENT_ERROR_NONE) {
681                 _ERR("Media Filter Creation Failed");
682                 return false;
683         }
684
685         switch (m->source_type) {
686         case SOURCE_TYPE_TV:
687                 snprintf(buf, sizeof(buf), "%s AND %s", MEDIA_CONDITION_MUSIC,
688                         MEDIA_CONDITION_INTERNAL);
689                 break;
690
691         case SOURCE_TYPE_USB:
692                 snprintf(buf, sizeof(buf), "%s AND %s", MEDIA_CONDITION_MUSIC,
693                         MEDIA_CONDITION_EXTERNAL);
694                 break;
695
696         case SOURCE_TYPE_ALL:
697         default:
698                 snprintf(buf, sizeof(buf), "%s", MEDIA_CONDITION_MUSIC);
699                 break;
700         }
701
702         media_filter_set_condition(m->filter, buf,
703                 MEDIA_CONTENT_COLLATE_DEFAULT);
704
705         return true;
706 }
707
708
709 bool CMediadata::m_DestroyFilter(void)
710 {
711         if (media_filter_destroy(m->filter) != MEDIA_CONTENT_ERROR_NONE) {
712                 _ERR("Filter destroy failed");
713                 m->filter = NULL;
714                 return false;
715         }
716         m->filter = NULL;
717
718         return true;
719 }
720
721
722 int CMediadata::m_GetPlaylistList(void)
723 {
724         if (media_playlist_foreach_playlist_from_db(NULL, sm_CbEachPlaylist, this)) {
725                 _ERR(" Get each playlist failed ");
726                 return false;
727         }
728
729         return true;
730 }
731
732
733 void CMediadata::m_GetCategoryList(ECategoryType type)
734 {
735         CAlbumInfo *alinfo = NULL;
736         CCategoryInfo *catinfo = NULL;
737         void *obj = NULL;
738         Eina_List *l = NULL;
739         int count;
740         bool ret;
741
742         if (!m->albumlist)
743                 return;
744
745         count = 0;
746         EINA_LIST_FOREACH(m->albumlist, l, obj) {
747                 alinfo = (CAlbumInfo *)obj;
748                 if (type == CAT_TYPE_ARTIST)
749                         catinfo = CCategoryInfo::FindCategory(m->artistlist, alinfo->Artist());
750                 else
751                         catinfo = CCategoryInfo::FindCategory(m->genrelist, alinfo->Genre());
752
753                 if (!catinfo) {
754                         catinfo = new CCategoryInfo();
755
756                         ret = catinfo->Create();
757                         if (!ret) {
758                                 delete catinfo;
759                                 continue;
760                         }
761
762                         catinfo->SetCategoryId(++count);
763                         catinfo->SetAlbumCount(1);
764                         catinfo->SetSongCount(alinfo->SongCount());
765                         if (type == CAT_TYPE_ARTIST) {
766                                 if (alinfo->Artist())
767                                         catinfo->SetName(alinfo->Artist());
768                                 else
769                                         catinfo->SetName(_(MUSIC_STR_UNKNOWN));
770
771                                 m->artistlist = eina_list_append(
772                                         m->artistlist, catinfo);
773                         }
774                         else {
775                                 if (alinfo->Genre())
776                                         catinfo->SetName(alinfo->Genre());
777                                 else
778                                         catinfo->SetName(_(MUSIC_STR_UNKNOWN));
779
780                                 m->genrelist = eina_list_append(
781                                         m->genrelist, catinfo);
782                         }
783                 }
784                 else {
785                         catinfo->SetAlbumCount(catinfo->AlbumCount() + 1);
786                         catinfo->SetSongCount(catinfo->SongCount() + alinfo->SongCount());
787                 }
788
789                 catinfo->SetAlbumInfo(alinfo);
790         }
791 }
792
793
794 int CMediadata::m_GetPlaylistSongList(CCategoryInfo *catinfo)
795 {
796         media_info_h mdh;
797         Eina_List *l = NULL;
798         CCategoryInfo::CListMember *member = NULL;
799         void *obj = NULL;
800         int r;
801
802         if (!catinfo || !catinfo->MemberList()) {
803                 _ERR(" Invalid argument ");
804                 return false;
805         }
806
807         m->slist_type = E_PLAYLIST_SONGS;
808
809         EINA_LIST_FOREACH(catinfo->MemberList(), l, obj) {
810                 member = (CCategoryInfo::CListMember *)obj;
811                 if (!member->mediaId)
812                         continue;
813
814                 r = media_info_get_media_from_db(member->mediaId, &mdh);
815                 if (r != MEDIA_CONTENT_ERROR_NONE) {
816                         _ERR("unable to get handle from id");
817                         continue;
818                 }
819
820                 m->member_id = member->memberId;
821                 if (!m_HandleEachMediaData(mdh))
822                         _ERR("unable to get media data");
823         }
824
825         return true;
826 }
827
828
829 int CMediadata::m_GetFolderSongList(CFolderInfo *finfo)
830 {
831         char *id = NULL;
832         int r;
833
834         id = finfo->Id();
835
836         m->slist_type = E_FOLDER_SONGS;
837         r = media_folder_foreach_media_from_db(id, m->filter,
838                 sm_CbEachMediaData, (void *)this);
839         if (r != MEDIA_CONTENT_ERROR_NONE) {
840                 _ERR("Media folder foreach folder from db failed");
841                 return false;
842         }
843
844         return true;
845 }
846
847
848 int CMediadata::m_GetFolderList(void)
849 {
850         int r;
851
852         r = media_folder_foreach_folder_from_db(m->filter,
853                 sm_CbEachFolderData, (void *)this);
854         if (r != MEDIA_CONTENT_ERROR_NONE) {
855                 _ERR("Media album foreach album from db failed");
856                 return false;
857         }
858
859         return true;
860 }
861
862
863 int CMediadata::m_GetAlbumSongList(CAlbumInfo *alinfo)
864 {
865         int id;
866         int r;
867
868         id = alinfo->AlbumId();
869
870         m->slist_type = E_ALBUM_SONGS;
871         r = media_album_foreach_media_from_db(id, m->filter,
872                 sm_CbEachMediaData, (void *)this);
873         if (r != MEDIA_CONTENT_ERROR_NONE) {
874                 _ERR("Media folder foreach folder from db failed");
875                 return false;
876         }
877
878         return true;
879 }
880
881
882 int CMediadata::m_GetAlbumList(void)
883 {
884         int r;
885
886         r = media_album_foreach_album_from_db(m->filter,
887                 sm_CbEachAlbumData, (void *)this);
888         if (r != MEDIA_CONTENT_ERROR_NONE) {
889                 _ERR("Media album foreach album from db failed");
890                 return false;
891         }
892
893         return true;
894 }
895
896
897 int CMediadata::m_GetSongList(void)
898 {
899         int r;
900
901         m->slist_type = E_ALL_SONGS;
902         r = media_info_foreach_media_from_db(m->filter,
903                 sm_CbEachMediaData, (void *)this);
904         if (r != MEDIA_CONTENT_ERROR_NONE) {
905                 _ERR("Media folder foreach folder from db failed");
906                 return false;
907         }
908
909         return true;
910 }
911
912
913 void CMediadata::m_UpdateLists(void)
914 {
915         bool r;
916
917         r = m_CreateFilter();
918         if (r == false) {
919                 _ERR("Media Filter Creation Failed");
920                 return;
921         }
922
923         if (m->songlist)
924                 m_DeleteSongList();
925         m_GetSongList();
926
927         if (m->albumlist)
928                 m_DeleteAlbumList();
929         m_GetAlbumList();
930
931         if (m->artistlist)
932                 m_DeleteCategoryList(CAT_TYPE_ARTIST);
933         m_GetCategoryList(CAT_TYPE_ARTIST);
934
935         if (m->genrelist)
936                 m_DeleteCategoryList(CAT_TYPE_GENRE);
937         m_GetCategoryList(CAT_TYPE_GENRE);
938
939         if (m->folderlist)
940                 m_DeleteFolderList();
941         m_GetFolderList();
942
943         r = m_DestroyFilter();
944         if (r == false)
945                 _ERR("Media Filter Creation Failed");
946 }
947
948
949 bool CMediadata::Create(void)
950 {
951         if (m)
952                 return false;
953         
954         m = new SMediadata;
955         if (!m) {
956                 _ERR("m calloc failed");
957                 return false;
958         }
959
960         int r;
961         r = media_content_connect();
962         if (r != MEDIA_CONTENT_ERROR_NONE) {
963                 _ERR("Media Content Connect Failed");
964                 delete m;
965                 m = NULL;
966                 return false;
967         }
968
969         CMediaContentDbUpdateListener::Create();
970
971         m->source_type = SOURCE_TYPE_NONE;
972
973         return true;
974 }
975
976
977 void CMediadata::Destroy(void)
978 {
979         if (!m)
980                 return;
981
982         int r;
983         struct SCbInfo *cbinfo;
984         void *obj;
985
986         m_DeleteSongList();
987         m_DeleteAlbumList();
988         m_DeleteAlbumSongList();
989         m_DeleteFolderList();
990         m_DeleteFolderSongList();
991         m_DeleteCategoryList(CAT_TYPE_ARTIST);
992         m_DeleteCategoryList(CAT_TYPE_GENRE);
993         m_DeleteCategoryList(CAT_TYPE_PLAYLISTS);
994         m_DeletePlaylistSongList();
995         if (m->sinfo && m->sinfo->FlagCreate())
996                 m->sinfo->Destroy();
997         delete m->sinfo;
998
999         EINA_LIST_FREE(m->cblist, obj) {
1000                 cbinfo = (SCbInfo *)obj;
1001                 free(cbinfo);
1002         }
1003
1004         CMediaContentDbUpdateListener::Destroy();
1005
1006         r = media_content_disconnect();
1007         if (r != MEDIA_CONTENT_ERROR_NONE)
1008                 _ERR("Media Content Connect Failed");
1009
1010         delete m;
1011 }
1012
1013
1014 struct SCbInfo *CMediadata::AddCallback(int type,
1015                 void (*cb)(void *), void *data)
1016 {
1017         struct SCbInfo *cbinfo;
1018
1019         if (!m || !cb)
1020                 return NULL;
1021
1022         cbinfo = (SCbInfo *)calloc(1, sizeof(*cbinfo));
1023         if (!cbinfo)
1024                 return NULL;
1025
1026         cbinfo->cb = cb;
1027         cbinfo->data = data;
1028         cbinfo->type = type;
1029
1030         m->cblist = eina_list_append(m->cblist, cbinfo);
1031
1032         return cbinfo;
1033 }
1034
1035
1036 bool CMediadata::RemoveCallback(struct SCbInfo *cbinfo)
1037 {
1038         if (!m)
1039                 return false;
1040
1041         if (!cbinfo)
1042                 return false;
1043
1044         m->cblist = eina_list_remove(m->cblist,
1045                         cbinfo);
1046         free(cbinfo);
1047
1048         return true;
1049 }
1050
1051
1052
1053 Eina_List *CMediadata::Medialist(int source_type, int EListType, void *info)
1054 {
1055         if (!m)
1056                 return NULL;
1057
1058         if (source_type != m->source_type) {
1059                 m->source_type = source_type;
1060                 m_UpdateLists();
1061         }
1062
1063         switch (EListType) {
1064         case LIST_TYPE_SONG:
1065                 return m->songlist;
1066
1067         case LIST_TYPE_ALBUM:
1068                 return m->albumlist;
1069
1070         case LIST_TYPE_ALBUM_SONG:
1071                 if (m->album_songlist)
1072                         m_DeleteAlbumSongList();
1073                 m_GetAlbumSongList((CAlbumInfo *)info);
1074                 return m->album_songlist;
1075
1076         case LIST_TYPE_FOLDER:
1077                 return m->folderlist;
1078
1079         case LIST_TYPE_FOLDER_SONG:
1080                 if (m->folder_songlist)
1081                         m_DeleteFolderSongList();
1082                 m_GetFolderSongList((CFolderInfo *)info);
1083                 return m->folder_songlist;
1084
1085         case LIST_TYPE_ARTIST:
1086                 return m->artistlist;
1087
1088         case LIST_TYPE_GENRE:
1089                 return m->genrelist;
1090
1091         case LIST_TYPE_PLAYLISTS:
1092                 if (m->playlistslist)
1093                         m_DeleteCategoryList(CAT_TYPE_PLAYLISTS);
1094                 m_GetPlaylistList();
1095                 return m->playlistslist;
1096
1097         case LIST_TYPE_PLAYLISTS_SONG:
1098                 if (m->playlist_songlist)
1099                         m_DeletePlaylistSongList();
1100                 m_GetPlaylistSongList((CCategoryInfo *)info);
1101                 return m->playlist_songlist;
1102
1103         default:
1104                 _ERR(" Wrong list type ");
1105                 break;
1106         }
1107
1108         return NULL;
1109 }
1110
1111 CSongInfo *CMediadata::SongByUri(char *uri)
1112 {
1113         if (!m)
1114                 return NULL;
1115
1116         filter_h filter;
1117         char buf[MAX_LENGTH];
1118         int r;
1119
1120         if (!uri)
1121                 return NULL;
1122
1123         if (m->sinfo && m->sinfo->FlagCreate()) {
1124                 m->sinfo->Destroy();
1125         }
1126
1127         delete m->sinfo;
1128         m->sinfo = NULL;
1129
1130         r = media_filter_create(&filter);
1131         if (r != MEDIA_CONTENT_ERROR_NONE) {
1132                 _ERR("Media Filter Creation Failed");
1133                 return NULL;
1134         }
1135
1136         snprintf(buf, sizeof(buf), "%s AND (MEDIA_PATH LIKE '%s%%')",
1137                         MEDIA_CONDITION_MUSIC,
1138                         uri);
1139
1140         media_filter_set_condition(filter, buf,
1141                         MEDIA_CONTENT_COLLATE_DEFAULT);
1142
1143         m->slist_type = E_SINGLE_SONG;
1144         r = media_info_foreach_media_from_db(filter, sm_CbEachMediaData,
1145                         (void *)this);
1146         if (r != MEDIA_CONTENT_ERROR_NONE)
1147                 _ERR("Failed to fetch media info");
1148
1149         if (media_filter_destroy(filter) != MEDIA_CONTENT_ERROR_NONE)
1150                 _ERR("Filter destroy failed");
1151
1152         return m->sinfo;
1153 }
1154
1155
1156 bool CMediadata::SetPlayedTime(char *media_id)
1157 {
1158         if (!m)
1159                 return false;
1160
1161         media_info_h mdh;
1162         audio_meta_h adh;
1163         time_t ptime;
1164         int r;
1165
1166         if (!media_id) {
1167                 _ERR("Invalid parameter");
1168                 return false;
1169         }
1170
1171         r = media_info_get_media_from_db(media_id, &mdh);
1172         if (r != MEDIA_CONTENT_ERROR_NONE) {
1173                 _ERR("Failed to get media from id");
1174                 return false;
1175         }
1176
1177         r = media_info_get_audio(mdh, &adh);
1178         if (r != MEDIA_CONTENT_ERROR_NONE) {
1179                 _ERR("Failed to get audio from media");
1180                 media_info_destroy(mdh);
1181                 return false;
1182         }
1183
1184         ptime = time(NULL);
1185
1186         r = audio_meta_set_played_time(adh, ptime);
1187         if (r != MEDIA_CONTENT_ERROR_NONE) {
1188                 _ERR("Failed to set played time");
1189                 audio_meta_destroy(adh);
1190                 media_info_destroy(mdh);
1191                 return false;
1192         }
1193
1194         r = audio_meta_update_to_db(adh);
1195         if (r != MEDIA_CONTENT_ERROR_NONE) {
1196                 _ERR("Failed to update to db");
1197                 audio_meta_destroy(adh);
1198                 media_info_destroy(mdh);
1199                 return false;
1200         }
1201
1202         audio_meta_destroy(adh);
1203         media_info_destroy(mdh);
1204
1205         return true;
1206 }
1207
1208
1209 bool CMediadata::InsertPlaylist(const char *name, Eina_List *idlist)
1210 {
1211         if (!m)
1212                 return false;
1213
1214         media_playlist_h ph;
1215         int r;
1216         Eina_List *l;
1217         char *id = NULL;
1218         void *obj;
1219
1220         if (!name)
1221                 return false;
1222
1223         r = media_playlist_insert_to_db(name, &ph);
1224         if (r != MEDIA_CONTENT_ERROR_NONE) {
1225                 _ERR(" Failed to insert ");
1226                 return false;
1227         }
1228
1229         EINA_LIST_FOREACH(idlist, l, obj) {
1230                 id = (char *)obj;
1231                 media_playlist_add_media(ph, id);
1232         }
1233
1234         media_playlist_update_to_db(ph);
1235
1236         return true;
1237 }
1238
1239
1240 bool CMediadata::ExistPlaylist(const char *name)
1241 {
1242         if (!m)
1243                 return false;
1244
1245         Eina_List *l;
1246         CCategoryInfo *catinfo;
1247         void *obj;
1248
1249         if (!name)
1250                 return false;
1251
1252         if (!m->playlistslist)
1253                 return false;
1254
1255         EINA_LIST_FOREACH(m->playlistslist, l, obj) {
1256                 catinfo = (CCategoryInfo *)obj;
1257                 if (catinfo->Name() && !strcmp(catinfo->Name(), name))
1258                         return true;
1259         }
1260
1261         return false;
1262 }
1263
1264
1265 bool CMediadata::DeletePlaylist(int id)
1266 {
1267         if (!m)
1268                 return false;
1269
1270         int r;
1271
1272         r = media_playlist_delete_from_db(id);
1273         if (r != MEDIA_CONTENT_ERROR_NONE) {
1274                 _ERR(" Failed to delete playlist");
1275                 return false;
1276         }
1277
1278         return true;
1279 }
1280
1281
1282 bool CMediadata::RenamePlaylist(int id, const char *name)
1283 {
1284         if (!m)
1285                 return false;
1286
1287         int r;
1288         media_playlist_h ph;
1289
1290         r = media_playlist_get_playlist_from_db(id, &ph);
1291         if (r != MEDIA_CONTENT_ERROR_NONE) {
1292                 _ERR(" Failed to get playlist");
1293                 return false;
1294         }
1295
1296         r = media_playlist_set_name(ph, name);
1297         if (r != MEDIA_CONTENT_ERROR_NONE) {
1298                 _ERR(" Failed to set playlist name");
1299                 return false;
1300         }
1301
1302         media_playlist_update_to_db(ph);
1303
1304         return true;
1305 }
1306
1307
1308 bool CMediadata::AddmediaPlaylist(int lid, Eina_List *idlist)
1309 {
1310         if (!m)
1311                 return false;
1312
1313         media_playlist_h ph;
1314         int r;
1315         Eina_List *l;
1316         char *id;
1317         void *obj;
1318
1319         if (!idlist)
1320                 return false;
1321
1322         r = media_playlist_get_playlist_from_db(lid, &ph);
1323         if (r != MEDIA_CONTENT_ERROR_NONE) {
1324                 _ERR(" Failed to get playlist");
1325                 return false;
1326         }
1327
1328         EINA_LIST_FOREACH(idlist, l, obj) {
1329                 id = (char *)obj;
1330                 media_playlist_add_media(ph, id);
1331         }
1332
1333         media_playlist_update_to_db(ph);
1334
1335         return true;
1336 }
1337
1338
1339 bool CMediadata::RemovemediaPlaylist(int lid, Eina_List *idlist)
1340 {
1341         if (!m)
1342                 return false;
1343
1344         media_playlist_h ph;
1345         int r;
1346         Eina_List *l;
1347         CSongInfo *sinfo;
1348         void *obj;
1349         int id;
1350
1351         if (!idlist) {
1352                 _ERR(" Invalid argument ");
1353                 return false;
1354         }
1355
1356         r = media_playlist_get_playlist_from_db(lid, &ph);
1357         if (r != MEDIA_CONTENT_ERROR_NONE) {
1358                 _ERR(" Failed to get playlist");
1359                 return false;
1360         }
1361
1362         EINA_LIST_FOREACH(idlist, l, obj) {
1363                 sinfo = (CSongInfo *)obj;
1364                 id = sinfo->MemberId();
1365                 if (id)
1366                         media_playlist_remove_media(ph, id);
1367         }
1368
1369         media_playlist_update_to_db(ph);
1370
1371         return true;
1372 }
1373
1374
1375 Eina_List *CMediadata::PlaylistsForCtxt(void)
1376 {
1377         Eina_List *list;
1378
1379         list = NULL;
1380         if (media_playlist_foreach_playlist_from_db(NULL, sm_CbPlaylist, &list))
1381                 _ERR(" Get playlist failed ");
1382
1383         return list;
1384 }
1385
1386
1387 void CMediadata::OnUpdated(const SEntity *entity)
1388 {
1389         Eina_List *l = NULL;
1390         SCbInfo *cbinfo = NULL;
1391         void *obj = NULL;
1392
1393         if (entity->err != MEDIA_CONTENT_ERROR_NONE || !m)
1394                 return;
1395
1396         m->source_type = SOURCE_TYPE_NONE;
1397         EINA_LIST_FOREACH(m->cblist, l, obj) {
1398                 cbinfo = (SCbInfo *)obj;
1399                 if (cbinfo->type == E_CONTENT_UPDATE && cbinfo->cb)
1400                         cbinfo->cb(cbinfo->data);
1401         }
1402 }